diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs index 2bd0c4224..990ce67d7 100644 --- a/NETGenerator/NETGenerator.cs +++ b/NETGenerator/NETGenerator.cs @@ -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); diff --git a/SemanticTree/AbstractVisitor.cs b/SemanticTree/AbstractVisitor.cs index 9ac335081..77c86c8b2 100644 --- a/SemanticTree/AbstractVisitor.cs +++ b/SemanticTree/AbstractVisitor.cs @@ -651,6 +651,11 @@ namespace PascalABCCompiler.SemanticTree { } + + public virtual void visit(ITypeOfOperatorAsConstant value) + { + + } } } diff --git a/SemanticTree/IVisitor.cs b/SemanticTree/IVisitor.cs index 09679e948..c5e631224 100644 --- a/SemanticTree/IVisitor.cs +++ b/SemanticTree/IVisitor.cs @@ -301,6 +301,8 @@ namespace PascalABCCompiler.SemanticTree void visit(IDefaultOperatorNodeAsConstant value); void visit(IDoubleQuestionColonExpressionNode value); + + void visit(ITypeOfOperatorAsConstant value); } } diff --git a/SemanticTree/SemanticTree.cs b/SemanticTree/SemanticTree.cs index c3ef40bf0..a567a3d71 100644 --- a/SemanticTree/SemanticTree.cs +++ b/SemanticTree/SemanticTree.cs @@ -1867,7 +1867,15 @@ namespace PascalABCCompiler.SemanticTree } } - public interface ICompiledConstructorCallAsConstant : IConstantNode + public interface ITypeOfOperatorAsConstant : IConstantNode + { + ITypeOfOperator TypeOfOperator + { + get; + } + } + + public interface ICompiledConstructorCallAsConstant : IConstantNode { ICompiledConstructorCall MethodCall { diff --git a/TestSuite/attributes3.pas b/TestSuite/attributes3.pas new file mode 100644 index 000000000..5ba4db91e --- /dev/null +++ b/TestSuite/attributes3.pas @@ -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. \ No newline at end of file diff --git a/TestSuite/errors/err0406.pas b/TestSuite/errors/err0406.pas new file mode 100644 index 000000000..72a4dbe4f --- /dev/null +++ b/TestSuite/errors/err0406.pas @@ -0,0 +1,4 @@ +const c: System.Type = typeof(integer); +begin + writeln(c); +end. \ No newline at end of file diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 7a41c57af..de735b483 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -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; diff --git a/TreeConverter/TreeRealization/base_nodes.cs b/TreeConverter/TreeRealization/base_nodes.cs index de6892ebf..4d4c8923e 100644 --- a/TreeConverter/TreeRealization/base_nodes.cs +++ b/TreeConverter/TreeRealization/base_nodes.cs @@ -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 }; /// diff --git a/TreeConverter/TreeRealization/constants.cs b/TreeConverter/TreeRealization/constants.cs index 4028f6712..c278397a0 100644 --- a/TreeConverter/TreeRealization/constants.cs +++ b/TreeConverter/TreeRealization/constants.cs @@ -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; + } + } + + + /// + /// Метод для обхода дерева посетителем. + /// + /// Класс - посетитель дерева. + public override void visit(SemanticTree.ISemanticVisitor visitor) + { + visitor.visit(this); + } + + /// + /// Тип узла. + /// + 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; diff --git a/VisualPlugins/LanguageConverter/Source/Visitor.cs b/VisualPlugins/LanguageConverter/Source/Visitor.cs index e69a5d5de..dafdeadeb 100644 --- a/VisualPlugins/LanguageConverter/Source/Visitor.cs +++ b/VisualPlugins/LanguageConverter/Source/Visitor.cs @@ -1559,5 +1559,10 @@ namespace VisualPascalABCPlugins { throw new System.NotImplementedException(); } + + public void visit(ITypeOfOperatorAsConstant value) + { + throw new System.NotImplementedException(); + } } } diff --git a/VisualPlugins/SemanticTreeVisualisator/Source/Visitor.cs b/VisualPlugins/SemanticTreeVisualisator/Source/Visitor.cs index 47070b483..941eb8d3a 100644 --- a/VisualPlugins/SemanticTreeVisualisator/Source/Visitor.cs +++ b/VisualPlugins/SemanticTreeVisualisator/Source/Visitor.cs @@ -2565,5 +2565,10 @@ namespace VisualPascalABCPlugins { throw new System.NotImplementedException(); } + + public void visit(ITypeOfOperatorAsConstant value) + { + throw new System.NotImplementedException(); + } } }