From 2e9800d98da7e8b39ab818fc68cd4e9fa4ad51a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=BE=D0=BD=D0=B4=D0=B0=D1=80=D0=B5=D0=B2=20=D0=98?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD?= Date: Tue, 2 Aug 2016 21:38:16 +0200 Subject: [PATCH] bug fix #228 --- TestSuite/errors/err0221.pas | 7 ++++ TestSuite/generic_predef1.pas | 19 +++++++++++ .../TreeConversion/syntax_tree_visitor.cs | 34 ++++++++++++++++--- bin/Lng/Eng/SemanticErrors_ib.dat | 2 ++ bin/Lng/Rus/SemanticErrors_ib.dat | 2 ++ 5 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 TestSuite/errors/err0221.pas create mode 100644 TestSuite/generic_predef1.pas diff --git a/TestSuite/errors/err0221.pas b/TestSuite/errors/err0221.pas new file mode 100644 index 000000000..6eb87d866 --- /dev/null +++ b/TestSuite/errors/err0221.pas @@ -0,0 +1,7 @@ +type TNode = class; +TNode = class +a: T1; +end; +begin + +end. \ No newline at end of file diff --git a/TestSuite/generic_predef1.pas b/TestSuite/generic_predef1.pas new file mode 100644 index 000000000..c0a412db1 --- /dev/null +++ b/TestSuite/generic_predef1.pas @@ -0,0 +1,19 @@ +type TNode = class; +TList = class +node: TNode; +end; + +TNode = class +a: T; +lst: TList; +end; + +begin +var n := new TNode; +n.a := 1; +var lst := new TList; +lst.node := n; +n.lst := lst; +assert(n.a = 1); +assert(lst.node.a = 1); +end. \ No newline at end of file diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index d68f8c9f6..87884bee0 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -10482,11 +10482,19 @@ _type_declaration.type_def is SyntaxTree.ref_type || _type_declaration.type_def //Ошибка, т.к. нет списка шаблонных параметров. AddError(get_location(_type_declaration.type_name), "TEMPLATE_PARAMS_EXPECTED"); } + bool predefined_generic = false; if (is_generic) { - context.check_name_free(_type_declaration.type_name.name, get_location(_type_declaration.type_name)); + SymbolInfo si = context.find_only_in_namespace(_type_declaration.type_name.name + compiler_string_consts.generic_params_infix + + cl_def.template_args.idents.Count.ToString()); + if (!(si != null && si.sym_info is common_type_node && context.types_predefined.IndexOf(si.sym_info as common_type_node) != -1)) + { + context.check_name_free(_type_declaration.type_name.name, get_location(_type_declaration.type_name)); + } + else + predefined_generic = true; _type_declaration.type_name.name += compiler_string_consts.generic_params_infix + - cl_def.template_args.idents.Count.ToString(); + cl_def.template_args.idents.Count.ToString(); } if (cl_def.keyword == SyntaxTree.class_keyword.Record) { @@ -10516,9 +10524,27 @@ _type_declaration.type_def is SyntaxTree.ref_type || _type_declaration.type_def assign_doc_info(ctn,_type_declaration); if (is_generic) { - context.create_generic_indicator(ctn); - visit_generic_params(ctn, cl_def.template_args.idents); + if (predefined_generic) + { + if (ctn.generic_params.Count != cl_def.template_args.idents.Count) + AddError(get_location(cl_def.template_args), "GENERIC_PARAMETERS_MISMATCH"); + foreach (ident id in cl_def.template_args.idents) + { + SymbolInfo si = ctn.find_in_type(id.name); + if (si == null) + AddError(get_location(cl_def.template_args), "GENERIC_PARAMETERS_MISMATCH"); + if (!(si.sym_info is common_type_node && (si.sym_info as common_type_node).is_generic_parameter)) + AddError(get_location(cl_def.template_args), "GENERIC_PARAMETERS_MISMATCH"); + } + } + else + { + context.create_generic_indicator(ctn); + visit_generic_params(ctn, cl_def.template_args.idents); + } } + if (predefined_generic && cl_def.where_section != null && cl_def.where_section.defs.Count > 0) + AddError(get_location(cl_def.where_section), "WHERE_SECTION_NOT_ALLOWED"); visit_where_list(cl_def.where_section); CheckWaitedRefTypes(ctn); is_direct_type_decl = true; diff --git a/bin/Lng/Eng/SemanticErrors_ib.dat b/bin/Lng/Eng/SemanticErrors_ib.dat index 1d9f773fe..7414317b1 100644 --- a/bin/Lng/Eng/SemanticErrors_ib.dat +++ b/bin/Lng/Eng/SemanticErrors_ib.dat @@ -121,6 +121,8 @@ IMPLICIT_EXPLICIT_OPERATOR_EXTENSION_ONLY_FOR_COMPILED_CLASSES_ALLOWED=Operators EXTENSIONMETHOD_KEYWORD_NOT_ALLOWED=extensionmethod is not allowed in this context CANNOT_EXTEND_STANDARD_OPERATORS_FOR_DELEGATE=Can not extend operators +,+=,-,-= for delegates FORWARD_EXTENSION_METHODS_NOT_ALLOWED=forward attribute can not be applied to extension methods +WHERE_SECTION_NOT_ALLOWED=Can not apply 'where' to predefined class +GENERIC_PARAMETERS_MISMATCH=Generic-parameters mismatch %PREFIX%=COMPILATIONERROR_ UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Unit expected, library found ASSEMBLY_{0}_READING_ERROR=Error by reading assembly '{0}' diff --git a/bin/Lng/Rus/SemanticErrors_ib.dat b/bin/Lng/Rus/SemanticErrors_ib.dat index c97384c64..97f09af92 100644 --- a/bin/Lng/Rus/SemanticErrors_ib.dat +++ b/bin/Lng/Rus/SemanticErrors_ib.dat @@ -116,6 +116,8 @@ IMPLICIT_EXPLICIT_OPERATOR_EXTENSION_ONLY_FOR_COMPILED_CLASSES_ALLOWED=extension EXTENSIONMETHOD_KEYWORD_NOT_ALLOWED=Атрибут extensionmethod недопустим в данном контексте CANNOT_EXTEND_STANDARD_OPERATORS_FOR_DELEGATE=Нельзя раширять операции +,+=,-,-= для делегатов FORWARD_EXTENSION_METHODS_NOT_ALLOWED=Атрибут forward недопустим для методов расширения +WHERE_SECTION_NOT_ALLOWED=Секция where недопустима в данном контексте +GENERIC_PARAMETERS_MISMATCH=Generic-параметры не совпадают с generic-параметрами в предописании типа %PREFIX%=COMPILATIONERROR_ UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Ожидался модуль, а встречена библиотека ASSEMBLY_{0}_READING_ERROR=Ошибка при чтении сборки '{0}'