From 7e57cb301d6539b702636b26fec00157deed5b5e 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: Sun, 31 May 2020 13:37:25 +0200 Subject: [PATCH] bug fix #2245 --- Compiler/PCU/PCUWriter.cs | 94 +++++++++++++++++++++++------ TestSuite/CompilationSamples/u1.pas | 8 +++ TestSuite/CompilationSamples/u2.pas | 12 ++++ TestSuite/CompilationSamples/u3.pas | 16 +++++ TestSuite/CompilationSamples/u4.pas | 23 +++++++ 5 files changed, 135 insertions(+), 18 deletions(-) create mode 100644 TestSuite/CompilationSamples/u1.pas create mode 100644 TestSuite/CompilationSamples/u2.pas create mode 100644 TestSuite/CompilationSamples/u3.pas create mode 100644 TestSuite/CompilationSamples/u4.pas diff --git a/Compiler/PCU/PCUWriter.cs b/Compiler/PCU/PCUWriter.cs index 6b7febeba..db55758fe 100644 --- a/Compiler/PCU/PCUWriter.cs +++ b/Compiler/PCU/PCUWriter.cs @@ -869,6 +869,50 @@ namespace PascalABCCompiler.PCU } //\ssyy + + private void AddIndirectUsedUnitsForType(type_node tn, Dictionary ns_dict, bool interf) + { + if (tn is common_type_node) + { + common_namespace_node comp_cnn = (tn as common_type_node).comprehensive_namespace; + if (comp_cnn != null && !ns_dict.ContainsKey(comp_cnn)) + { + if (interf) + unit.InterfaceUsedUnits.AddElement(comp_cnn.cont_unit); + else + unit.ImplementationUsedUnits.AddElement(comp_cnn.cont_unit); + ns_dict[comp_cnn] = true; + } + } + } + + private void AddIndirectUsedUnitsInStatement(statement_node stmt, Dictionary ns_dict, bool interf) + { + if (stmt == null) + return; + if (stmt is statements_list) + { + statements_list stmt_list = stmt as statements_list; + foreach (local_block_variable lv in stmt_list.local_variables) + { + AddIndirectUsedUnitsForType(lv.type, ns_dict, interf); + } + foreach (statement_node st in stmt_list.statements) + AddIndirectUsedUnitsInStatement(st, ns_dict, interf); + } + + } + + private void AddIndirectUsedUnitsInVariables(IEnumerable variables, Dictionary ns_dict, bool interf) where T: var_definition_node + { + if (variables == null) + return; + foreach (var lv in variables) + { + AddIndirectUsedUnitsForType(lv.type, ns_dict, interf); + } + } + private void AddIndirectInteraceUsedUnits() { if (cun.namespaces.Count == 0) @@ -893,19 +937,28 @@ namespace PascalABCCompiler.PCU { foreach (common_parameter cp in cmn.parameters) { - if (cp.type is common_type_node) - { - common_namespace_node comp_cnn = (cp.type as common_type_node).comprehensive_namespace; - if (comp_cnn != null && !interf_ns_dict.ContainsKey(comp_cnn)) - { - unit.InterfaceUsedUnits.AddElement(comp_cnn.cont_unit); - interf_ns_dict[comp_cnn] = true; - } - } + AddIndirectUsedUnitsForType(cp.type, interf_ns_dict, true); } } + AddIndirectUsedUnitsInVariables(cmn.var_definition_nodes_list, interf_ns_dict, true); + AddIndirectUsedUnitsInStatement(cmn.function_code, interf_ns_dict, true); + if (cmn.return_value_type != null) + AddIndirectUsedUnitsForType(cmn.return_value_type, interf_ns_dict, true); } + AddIndirectUsedUnitsInVariables(ctn.fields, interf_ns_dict, true); } + foreach (common_namespace_function_node cnfn in cnn.functions) + { + AddIndirectUsedUnitsInVariables(cnfn.var_definition_nodes_list, interf_ns_dict, true); + AddIndirectUsedUnitsInStatement(cnfn.function_code, interf_ns_dict, true); + if (cnfn.return_value_type != null) + AddIndirectUsedUnitsForType(cnfn.return_value_type, interf_ns_dict, true); + } + AddIndirectUsedUnitsInVariables(cnn.variables, interf_ns_dict, true); + if (cun.main_function != null) + AddIndirectUsedUnitsInStatement(cun.main_function.function_code, interf_ns_dict, true); + if (cun.finalization_method != null) + AddIndirectUsedUnitsInStatement(cun.finalization_method.function_code, interf_ns_dict, true); } private void AddIndirectImplementationUsedUnits() @@ -932,19 +985,24 @@ namespace PascalABCCompiler.PCU { foreach (common_parameter cp in cmn.parameters) { - if (cp.type is common_type_node) - { - common_namespace_node comp_cnn = (cp.type as common_type_node).comprehensive_namespace; - if (comp_cnn != null && !impl_ns_dict.ContainsKey(comp_cnn)) - { - unit.ImplementationUsedUnits.AddElement(comp_cnn.cont_unit); - impl_ns_dict[comp_cnn] = true; - } - } + AddIndirectUsedUnitsForType(cp.type, impl_ns_dict, false); } } + AddIndirectUsedUnitsInVariables(cmn.var_definition_nodes_list, impl_ns_dict, false); + AddIndirectUsedUnitsInStatement(cmn.function_code, impl_ns_dict, false); + if (cmn.return_value_type != null) + AddIndirectUsedUnitsForType(cmn.return_value_type, impl_ns_dict, false); } + AddIndirectUsedUnitsInVariables(ctn.fields, impl_ns_dict, false); } + foreach (common_namespace_function_node cnfn in cnn.functions) + { + AddIndirectUsedUnitsInVariables(cnfn.var_definition_nodes_list, impl_ns_dict, false); + AddIndirectUsedUnitsInStatement(cnfn.function_code, impl_ns_dict, true); + if (cnfn.return_value_type != null) + AddIndirectUsedUnitsForType(cnfn.return_value_type, impl_ns_dict, true); + } + AddIndirectUsedUnitsInVariables(cnn.variables, impl_ns_dict, true); } //заполнение списка подключаемых модулей diff --git a/TestSuite/CompilationSamples/u1.pas b/TestSuite/CompilationSamples/u1.pas new file mode 100644 index 000000000..f527f6e2a --- /dev/null +++ b/TestSuite/CompilationSamples/u1.pas @@ -0,0 +1,8 @@ +unit u1; + +uses WPFObjects; + +begin + // любое использование Window + var w := Window; +end. \ No newline at end of file diff --git a/TestSuite/CompilationSamples/u2.pas b/TestSuite/CompilationSamples/u2.pas new file mode 100644 index 000000000..1e4afefe6 --- /dev/null +++ b/TestSuite/CompilationSamples/u2.pas @@ -0,0 +1,12 @@ +unit u2; + +uses WPFObjects; + +procedure f; +begin + var w := Window; +end; + +begin + +end. \ No newline at end of file diff --git a/TestSuite/CompilationSamples/u3.pas b/TestSuite/CompilationSamples/u3.pas new file mode 100644 index 000000000..de6a08730 --- /dev/null +++ b/TestSuite/CompilationSamples/u3.pas @@ -0,0 +1,16 @@ +unit u3; + +interface + +implementation + +uses WPFObjects; + +procedure f; +begin + var w := Window; +end; + +begin + +end. \ No newline at end of file diff --git a/TestSuite/CompilationSamples/u4.pas b/TestSuite/CompilationSamples/u4.pas new file mode 100644 index 000000000..ab13213b5 --- /dev/null +++ b/TestSuite/CompilationSamples/u4.pas @@ -0,0 +1,23 @@ +unit u4; + +interface + +uses WPFObjects; + +type TClass = class + f := Window; + function myf := Window; +end; + +implementation + +uses WPFObjects; + +procedure f; +begin + var w := Window; +end; + +begin + var w := Window; +end. \ No newline at end of file