From 1e51c553fb193798d9cc9a3fd4e5d034283a2144 Mon Sep 17 00:00:00 2001 From: Ivan Bondarev Date: Tue, 12 Oct 2021 20:39:29 +0200 Subject: [PATCH] #2442 --- TestSuite/errors/err0428.pas | 15 +++++++++++++++ TestSuite/errors/err0429.pas | 16 ++++++++++++++++ TestSuite/errors/err0430.pas | 19 +++++++++++++++++++ .../TreeConversion/compilation_context.cs | 18 +++++++++++++++++- .../TreeConversion/syntax_tree_visitor.cs | 10 ++++++++-- 5 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 TestSuite/errors/err0428.pas create mode 100644 TestSuite/errors/err0429.pas create mode 100644 TestSuite/errors/err0430.pas diff --git a/TestSuite/errors/err0428.pas b/TestSuite/errors/err0428.pas new file mode 100644 index 000000000..a9c3a9966 --- /dev/null +++ b/TestSuite/errors/err0428.pas @@ -0,0 +1,15 @@ +type + t0 = partial abstract class + + end; + + t1 = sealed class(t0) + + end; + t0 = partial abstract class + procedure p1; abstract; + end; + +begin + new t1; +end. \ No newline at end of file diff --git a/TestSuite/errors/err0429.pas b/TestSuite/errors/err0429.pas new file mode 100644 index 000000000..7a00a4cba --- /dev/null +++ b/TestSuite/errors/err0429.pas @@ -0,0 +1,16 @@ +unit err0429; +type + t0 = partial abstract class + + end; + + t1 = sealed class(t0) + + end; + t0 = partial abstract class + procedure p1; abstract; + end; + +begin + new t1; +end. \ No newline at end of file diff --git a/TestSuite/errors/err0430.pas b/TestSuite/errors/err0430.pas new file mode 100644 index 000000000..9841ad8d9 --- /dev/null +++ b/TestSuite/errors/err0430.pas @@ -0,0 +1,19 @@ +unit err0430; + +interface +type + t0 = partial abstract class + + end; + + t1 = sealed class(t0) + + end; + t0 = partial abstract class + procedure p1; abstract; + end; + +implementation +begin + new t1; +end. \ No newline at end of file diff --git a/TreeConverter/TreeConversion/compilation_context.cs b/TreeConverter/TreeConversion/compilation_context.cs index a857a5ccb..c9b47966f 100644 --- a/TreeConverter/TreeConversion/compilation_context.cs +++ b/TreeConverter/TreeConversion/compilation_context.cs @@ -2932,7 +2932,7 @@ namespace PascalABCCompiler.TreeConverter } //Проверка типа на соответствие заявленным интерфейсам - private void check_implement_interfaces()//common_type_node cnode) + public void check_implement_interfaces()//common_type_node cnode) { //Переводим контекст в состояние разбора класса cnode //_ctn = cnode; @@ -3116,6 +3116,22 @@ namespace PascalABCCompiler.TreeConverter } } + public void check_abstracts_implemented(List types) + { + foreach (common_type_node ctn in types) + { + _ctn = ctn; + check_implement_interfaces(); + _ctn = null; + if (ctn.IsSealed && ctn.IsAbstract && !ctn.IsStatic) + if (ctn.AbstractReason == null) + AddError(ctn.loc, "ABSTRACT_CLASS_CANNOT_BE_SEALED"); + else + AddError(ctn.loc, ctn.AbstractReason.Explanation, ctn.name, ctn.AbstractReason.ObjName); + + } + } + //ssyy public void check_labels(List lab_list) { diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 8ddb2850a..dabd71a51 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -70,7 +70,7 @@ namespace PascalABCCompiler.TreeConverter public compilation_context context; private bool var_def_statement_converting; - + private List inherited_from_partials_list = new List(); public ContextChanger contextChanger; internal using_namespace_list using_list = new using_namespace_list(); @@ -202,6 +202,7 @@ namespace PascalABCCompiler.TreeConverter generic_param_abilities.Clear(); current_converted_method_not_in_class_defined = false; assign_is_converting = false; + inherited_from_partials_list.Clear(); motivation_keeper.reset(); SystemLibrary.SystemLibInitializer.NeedsToRestore.Clear(); type_section_converting = false; @@ -3036,6 +3037,7 @@ namespace PascalABCCompiler.TreeConverter statement_node init_statements = convert_weak(_unit_module.initialization_part); context.leave_code_block(); common_namespace_function_node initialization_function = null; + context.check_abstracts_implemented(inherited_from_partials_list); if (init_statements != null) { context.check_labels(context.converted_namespace.labels); @@ -3056,6 +3058,7 @@ namespace PascalABCCompiler.TreeConverter if (final_statements != null) { context.check_labels(context.converted_namespace.labels); + finalization_function = new common_namespace_function_node(compiler_string_consts.finalization_function_name, null, final_statements.location, context.converted_namespace, convertion_data_and_alghoritms.symbol_table.CreateScope(context.converted_namespace.scope)); finalization_function.function_code = final_statements; @@ -3758,6 +3761,8 @@ namespace PascalABCCompiler.TreeConverter AddError(get_location(_class_definition.class_parents.types[0]), "CAN_NOT_INHERIT_FROM_DELEGATE_TYPE"); } Hashtable used_interfs = new Hashtable(); + if (tn is common_type_node && (tn as common_type_node).IsPartial) + inherited_from_partials_list.Add(context.converted_type); //Если tn - это интерфейс if (tn.IsInterface) { @@ -11111,7 +11116,7 @@ namespace PascalABCCompiler.TreeConverter UpdateUnitDefinitionItemForUnit(_compiled_unit); hard_node_test_and_visit(_program_module.program_block); context.check_labels(context.converted_namespace.labels); - + context.check_abstracts_implemented(inherited_from_partials_list); // frninja 28/04/16 - режем мусорные методы хелперы yield { var toRemove = cnsn.functions.Where(m => m.is_yield_helper).ToArray(); @@ -11122,6 +11127,7 @@ namespace PascalABCCompiler.TreeConverter } // end frninja + common_namespace_function_node main_function = new common_namespace_function_node(compiler_string_consts.temp_main_function_name, null, null, cnsn, null); main_function.function_code = context.code;