This commit is contained in:
Ivan Bondarev 2021-02-21 11:40:39 +01:00
parent 55a09ac403
commit 4817fd07e1
11 changed files with 119 additions and 2 deletions

View file

@ -1190,6 +1190,7 @@ namespace PascalABCCompiler.NETGenerator
else
fb.SetConstant(constant_value.value);
}
}
private void PushConstantValue(IConstantNode cnst)
@ -1801,6 +1802,8 @@ namespace PascalABCCompiler.NETGenerator
lst.Add(cn.value);
objs[i] = lst.ToArray();
}
else if (cnsts[i] is ITypeOfOperatorAsConstant)
objs[i] = helper.GetTypeReference((cnsts[i] as ITypeOfOperatorAsConstant).TypeOfOperator.oftype).tp;
else
objs[i] = cnsts[i].value;
}
@ -11161,6 +11164,11 @@ namespace PascalABCCompiler.NETGenerator
value.DefaultOperator.visit(this);
}
public override void visit(ITypeOfOperatorAsConstant value)
{
value.TypeOfOperator.visit(this);
}
public override void visit(ICommonConstructorCallAsConstant value)
{
value.ConstructorCall.visit(this);

View file

@ -651,6 +651,11 @@ namespace PascalABCCompiler.SemanticTree
{
}
public virtual void visit(ITypeOfOperatorAsConstant value)
{
}
}
}

View file

@ -301,6 +301,8 @@ namespace PascalABCCompiler.SemanticTree
void visit(IDefaultOperatorNodeAsConstant value);
void visit(IDoubleQuestionColonExpressionNode value);
void visit(ITypeOfOperatorAsConstant value);
}
}

View file

@ -1867,7 +1867,15 @@ namespace PascalABCCompiler.SemanticTree
}
}
public interface ICompiledConstructorCallAsConstant : IConstantNode
public interface ITypeOfOperatorAsConstant : IConstantNode
{
ITypeOfOperator TypeOfOperator
{
get;
}
}
public interface ICompiledConstructorCallAsConstant : IConstantNode
{
ICompiledConstructorCall MethodCall
{

23
TestSuite/attributes3.pas Normal file
View file

@ -0,0 +1,23 @@
uses
System.ComponentModel;
type
MyClassConverter = class (TypeConverter)
end;
MyClass = class
private
fMyField: MyClass;
public
[TypeConverterAttribute(typeof(MyClassConverter))]
property MyProperty: MyClass read fMyField write fMyField;
end;
begin
var o := new MyClass;
o.MyProperty := o;
var props := o.GetType().GetProperties();
var attrs := props[0].GetCustomAttributes(false);
assert((attrs[0] as TypeConverterAttribute).ConverterTypeName.IndexOf('MyClassConverter') <> -1);
end.

View file

@ -0,0 +1,4 @@
const c: System.Type = typeof(integer);
begin
writeln(c);
end.

View file

@ -12512,6 +12512,7 @@ namespace PascalABCCompiler.TreeConverter
case semantic_node_type.string_const_node :
case semantic_node_type.enum_const :
case semantic_node_type.null_const_node :
case semantic_node_type.typeof_operator_as_constant:
return;
default:
AddError(loc, "CONSTANT_EXPRESSION_EXPECTED");
@ -14948,6 +14949,8 @@ namespace PascalABCCompiler.TreeConverter
}
else if (expr is default_operator_node)
constant = new default_operator_node_as_constant(expr as default_operator_node, null);
else if (expr is typeof_operator && !is_const_section)
constant = new typeof_operator_as_constant(expr as typeof_operator, null);
else
{
constant = expr as constant_node;

View file

@ -38,7 +38,8 @@ namespace PascalABCCompiler.TreeRealization
common_constructor_call_as_constant, array_initializer, record_initializer, default_operator, attribute_node,
pinvoke_node, basic_function_call_node_as_constant, compiled_static_field_reference_as_constant,
common_namespace_event, indefinite_definition_node, indefinite_type, indefinite_function_call, indefinite_reference,
wrapped_statement, wrapped_expression, default_operator_node_as_constant, double_question_colon_expression
wrapped_statement, wrapped_expression, default_operator_node_as_constant, double_question_colon_expression,
typeof_operator_as_constant
};
/// <summary>

View file

@ -1183,6 +1183,59 @@ namespace PascalABCCompiler.TreeRealization
}
}
public class typeof_operator_as_constant : constant_node, SemanticTree.ITypeOfOperatorAsConstant
{
private typeof_operator _typeof_operator;
public typeof_operator typeof_operator
{
get
{
return _typeof_operator;
}
set
{
_typeof_operator = value;
}
}
public typeof_operator_as_constant(typeof_operator typeof_operator, location loc)
:
base(typeof_operator.type, loc)
{
_typeof_operator = typeof_operator;
}
SemanticTree.ITypeOfOperator SemanticTree.ITypeOfOperatorAsConstant.TypeOfOperator
{
get
{
return _typeof_operator;
}
}
/// <summary>
/// Метод для обхода дерева посетителем.
/// </summary>
/// <param name="visitor">Класс - посетитель дерева.</param>
public override void visit(SemanticTree.ISemanticVisitor visitor)
{
visitor.visit(this);
}
/// <summary>
/// Тип узла.
/// </summary>
public override semantic_node_type semantic_node_type
{
get
{
return semantic_node_type.typeof_operator_as_constant;
}
}
}
public class compiled_constructor_call_as_constant : constant_node, SemanticTree.ICompiledConstructorCallAsConstant
{
private compiled_constructor_call _method_call;

View file

@ -1559,5 +1559,10 @@ namespace VisualPascalABCPlugins
{
throw new System.NotImplementedException();
}
public void visit(ITypeOfOperatorAsConstant value)
{
throw new System.NotImplementedException();
}
}
}

View file

@ -2565,5 +2565,10 @@ namespace VisualPascalABCPlugins
{
throw new System.NotImplementedException();
}
public void visit(ITypeOfOperatorAsConstant value)
{
throw new System.NotImplementedException();
}
}
}