From 9ee420d9e66cb678c0169f945546b2db55f7335d 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: Mon, 29 Jan 2018 20:14:36 +0100 Subject: [PATCH 1/3] bug fix #658 --- .../TreeConversion/syntax_tree_visitor.cs | 16 ++++++++++++++++ bin/Lng/Eng/SemanticErrors_ib.dat | 1 + bin/Lng/Rus/SemanticErrors_ib.dat | 1 + bin/Lng/Ukr/SemanticErrors_ib.dat | 1 + 4 files changed, 19 insertions(+) diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 95a177093..f6f7e5402 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -3575,6 +3575,22 @@ namespace PascalABCCompiler.TreeConverter if (tn.IsPointer) AddError(get_location(types[i]), "AUTO_CLASS_MUST_NOT_HAVE_POINTERS"); } + if (_class_definition.body != null) + foreach (class_members cl_mem in _class_definition.body.class_def_blocks) + { + foreach (declaration decl in cl_mem.members) + { + if (decl is var_def_statement) + { + type_definition type = (decl as var_def_statement).vars_type; + SyntaxTree.array_type arr = type as SyntaxTree.array_type; + if (type is SyntaxTree.class_definition || (arr != null && arr.indexers != null && arr.indexers.indexers.Count > 0 && arr.indexers.indexers[0] != null)) + { + AddError(get_location(type), "STRUCT_TYPE_DEFINITION_IN_AUTO_CLASS"); + } + } + } + } } //if (!SemanticRules.OrderIndependedNames) diff --git a/bin/Lng/Eng/SemanticErrors_ib.dat b/bin/Lng/Eng/SemanticErrors_ib.dat index bf753aa26..e112204e7 100644 --- a/bin/Lng/Eng/SemanticErrors_ib.dat +++ b/bin/Lng/Eng/SemanticErrors_ib.dat @@ -135,6 +135,7 @@ OVERRIDE_NOT_ALLOWED_FOR_SHORT_FUNCTIONS=Can not use override in short functions RETURN_VALUE_IMPLICIT_EXPLICIT_EXPECTED=Can not declare implicit and explicit operators without explicitly defined return type RETURN_TYPE_UNDEFINED_{0}=Return type of function {0} is not defined and cannot be deduced. Declare the return type explicitly. OPERATOR_RETURN_TYPE_UNDEFINED_{0}=Return type of operator {0} is not defined and cannot be deduced. Declare the return type explicitly. +STRUCT_TYPE_DEFINITION_IN_AUTO_CLASS=Field types in auto classes cannot be record or array definition %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 02b86cf95..89fa13fa4 100644 --- a/bin/Lng/Rus/SemanticErrors_ib.dat +++ b/bin/Lng/Rus/SemanticErrors_ib.dat @@ -130,6 +130,7 @@ OVERRIDE_NOT_ALLOWED_FOR_SHORT_FUNCTIONS=Нельзя использовать o RETURN_VALUE_IMPLICIT_EXPLICIT_EXPECTED=Тип возвращаемого значения в операторах implicit и explicit должен указываться явно RETURN_TYPE_UNDEFINED_{0}=Тип возвращаемого значения функции {0} не определен и не может быть выведен в данный момент. Укажите тип явно. OPERATOR_RETURN_TYPE_UNDEFINED_{0}=Тип возвращаемого значения оператора {0} не определен и не может быть выведен в данный момент. Укажите тип явно. +STRUCT_TYPE_DEFINITION_IN_AUTO_CLASS=Типы полей авто-класса не могут быть описанием записи или описанием массива с границами %PREFIX%=COMPILATIONERROR_ UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Ожидался модуль, а встречена библиотека ASSEMBLY_{0}_READING_ERROR=Ошибка при чтении сборки '{0}' diff --git a/bin/Lng/Ukr/SemanticErrors_ib.dat b/bin/Lng/Ukr/SemanticErrors_ib.dat index 3b244bc92..428fa881c 100644 --- a/bin/Lng/Ukr/SemanticErrors_ib.dat +++ b/bin/Lng/Ukr/SemanticErrors_ib.dat @@ -128,6 +128,7 @@ NAMESPACE_SHOULD_CONTAINS_ONLY_TYPES=В пространство имен мож RETURN_VALUE_IMPLICIT_EXPLICIT_EXPECTED=Тип возвращаемого значения в операторах implicit и explicit должен указываться явно RETURN_TYPE_UNDEFINED_{0}=Тип возвращаемого значения функции {0} не определен и не может быть выведен в данный момент. Укажите тип явно. OPERATOR_RETURN_TYPE_UNDEFINED_{0}=Тип возвращаемого значения оператора {0} не определен и не может быть выведен в данный момент. Укажите тип явно. +STRUCT_TYPE_DEFINITION_IN_AUTO_CLASS=Типы полей авто-класса не могут быть описанием записи или описанием массива с границами %PREFIX%=COMPILATIONERROR_ UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Очікувався модуль, а зустріли бібліотеку ASSEMBLY_{0}_READING_ERROR=Помилка при читанні збірки '{0}' From 28a64634ae8879fa5a40c911aef1520a566bafce 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: Mon, 29 Jan 2018 21:17:51 +0100 Subject: [PATCH 2/3] bug fix #648 --- TestSuite/extensionmethods26.pas | 13 +++++++++++++ TreeConverter/TreeConversion/syntax_tree_visitor.cs | 4 ++++ 2 files changed, 17 insertions(+) create mode 100644 TestSuite/extensionmethods26.pas diff --git a/TestSuite/extensionmethods26.pas b/TestSuite/extensionmethods26.pas new file mode 100644 index 000000000..9b2eec7b6 --- /dev/null +++ b/TestSuite/extensionmethods26.pas @@ -0,0 +1,13 @@ +begin + var a:array of char; + a := Arr('A','B','C'); + var b := a + 'D';//'D' is char + assert(b.First = 'A'); + assert(b is IEnumerable); + var c := a + 'DE';//'DE' is string + assert(c is IEnumerable); + assert(c.Last = 'E'); + var e := 'D' + a; + assert(e is IEnumerable); + assert(e.Last = '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 f6f7e5402..4309d842b 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -1088,6 +1088,8 @@ namespace PascalABCCompiler.TreeConverter } } } + if (name == "+" && right_type == SystemLibrary.SystemLibrary.char_type && left_type != SystemLibrary.SystemLibrary.string_type) + no_search_in_extension_methods = false; SymbolInfoList sil = left_type.find_in_type(name, left_type.Scope, no_search_in_extension_methods); int added_symbols = -1; SymbolInfoList sil2 = null; @@ -1096,6 +1098,8 @@ namespace PascalABCCompiler.TreeConverter //SymbolInfo si2 = right_type.find(name, context.CurrentScope); if (sil != null) sil = sil.copy(); + if (name == "+" && right_type != SystemLibrary.SystemLibrary.string_type && left_type == SystemLibrary.SystemLibrary.char_type) + no_search_in_extension_methods = false; sil2 = right_type.find_in_type(name, right_type.Scope, no_search_in_extension_methods); if ((sil != null) && (sil2 != null)) { From 07e102cd91a76476a9e6015f6b5b8996b5a2fdeb 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: Mon, 29 Jan 2018 21:47:42 +0100 Subject: [PATCH 3/3] fix in case on int64 --- TreeConverter/TreeConversion/syntax_tree_visitor.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 4309d842b..e9546a851 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -10032,7 +10032,7 @@ namespace PascalABCCompiler.TreeConverter AddError(cn.location, "CASE_CONSTANT_VARIANT_COINCIDE_WITH_ANOTHER"); basic_function_call eq_call = new basic_function_call(int64_eq_meth, cn.location); eq_call.parameters.AddElement(en); - eq_call.parameters.AddElement(cn); + eq_call.parameters.AddElement(scn); eq_calls.Add(eq_call); } else @@ -10049,10 +10049,10 @@ namespace PascalABCCompiler.TreeConverter basic_function_node int64_leq_meth = SystemLibrary.SystemLibrary.int64_type.find_first_in_type("<=", true).sym_info as basic_function_node; basic_function_call greq_call = new basic_function_call(int64_greq_meth, left_cn.location); greq_call.parameters.AddElement(en); - greq_call.parameters.AddElement(left_cn); + greq_call.parameters.AddElement(left_scn); basic_function_call leq_call = new basic_function_call(int64_leq_meth, right_cn.location); leq_call.parameters.AddElement(en); - leq_call.parameters.AddElement(right_cn); + leq_call.parameters.AddElement(right_scn); basic_function_node in_diap_meth = SystemLibrary.SystemLibrary.bool_type.find_first_in_type("and", true).sym_info as basic_function_node; basic_function_call in_diap_call = new basic_function_call(in_diap_meth, left_cn.location); in_diap_call.parameters.AddElement(greq_call); @@ -10118,7 +10118,7 @@ namespace PascalABCCompiler.TreeConverter AddError(cn.location, "CASE_CONSTANT_VARIANT_COINCIDE_WITH_ANOTHER"); basic_function_call eq_call = new basic_function_call(uint64_eq_meth, cn.location); eq_call.parameters.AddElement(en); - eq_call.parameters.AddElement(cn); + eq_call.parameters.AddElement(scn); eq_calls.Add(eq_call); } else @@ -10135,10 +10135,10 @@ namespace PascalABCCompiler.TreeConverter basic_function_node uint64_leq_meth = SystemLibrary.SystemLibrary.uint64_type.find_first_in_type("<=", true).sym_info as basic_function_node; basic_function_call greq_call = new basic_function_call(uint64_greq_meth, left_cn.location); greq_call.parameters.AddElement(en); - greq_call.parameters.AddElement(left_cn); + greq_call.parameters.AddElement(left_scn); basic_function_call leq_call = new basic_function_call(uint64_leq_meth, right_cn.location); leq_call.parameters.AddElement(en); - leq_call.parameters.AddElement(right_cn); + leq_call.parameters.AddElement(right_scn); basic_function_node in_diap_meth = SystemLibrary.SystemLibrary.bool_type.find_first_in_type("and", true).sym_info as basic_function_node; basic_function_call in_diap_call = new basic_function_call(in_diap_meth, left_cn.location); in_diap_call.parameters.AddElement(greq_call);