From b768075b81f3f8b3c28ec18d51bcd9d4fe92d5d7 Mon Sep 17 00:00:00 2001 From: miks1965 Date: Fri, 22 Jul 2016 13:00:58 +0300 Subject: [PATCH] bug fix #246 #244 --- Configuration/GlobalAssemblyInfo.cs | 2 +- Configuration/Version.defs | 4 +- PascalABCNET.axml | 236 ++++++++++-------- ReleaseGenerators/PascalABCNET_version.nsh | 2 +- .../MarkMethodHasYieldVisitor.cs | 4 +- .../ReplaceYieldWithLamdasVisitor.cs | 22 +- TestSuite/CompilationSamples/PABCSystem.pas | 2 +- TestSuite/errors/err0220.pas | 3 + TestSuite/sum_extension.pas | 4 + TestSuite/yieldnil.pas | 9 + .../convertion_data_and_alghoritms.cs | 64 ++++- .../TreeConversion/syntax_tree_visitor.cs | 14 +- bin/Lib/PABCRtl.dll | Bin 508928 -> 508928 bytes 13 files changed, 239 insertions(+), 127 deletions(-) create mode 100644 TestSuite/errors/err0220.pas create mode 100644 TestSuite/sum_extension.pas create mode 100644 TestSuite/yieldnil.pas diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index a69afe513..e8f92acfb 100644 --- a/Configuration/GlobalAssemblyInfo.cs +++ b/Configuration/GlobalAssemblyInfo.cs @@ -15,7 +15,7 @@ internal static class RevisionClass public const string Major = "3"; public const string Minor = "1"; public const string Build = "0"; - public const string Revision = "1278"; + public const string Revision = "1281"; public const string MainVersion = Major + "." + Minor; public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision; diff --git a/Configuration/Version.defs b/Configuration/Version.defs index f5caa6e13..b91ce9828 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ -%MINOR%=1 -%REVISION%=1278 %COREVERSION%=0 +%REVISION%=1281 +%MINOR%=1 %MAJOR%=3 diff --git a/PascalABCNET.axml b/PascalABCNET.axml index 04563a2ec..51603f520 100644 --- a/PascalABCNET.axml +++ b/PascalABCNET.axml @@ -1,10 +1,10 @@ - + - + - + \treeconverter\treeconversion\syntax_tree_visitor.cs public override void visit(SyntaxTree.indexer _indexer) @@ -15,7 +15,7 @@ - + \treeconverter\treeconversion\syntax_tree_visitor.cs private void indexer_as_expression_index(expression_node expr, SyntaxTree.expression_list parameters, @@ -26,7 +26,7 @@ - + \TreeConverter\TreeConversion\syntax_tree_visitor.cs public override void visit(SyntaxTree.semantic_expr_node sen) @@ -37,7 +37,7 @@ - + \treeconverter\treeconversion\syntax_tree_visitor.cs var fh = (_procedure_definition.proc_header as SyntaxTree.function_header); @@ -50,9 +50,9 @@ - + - + \treeconverter\treeconversion\syntax_tree_visitor.cs public override void visit(SyntaxTree.assign_tuple _modern_proc_type) @@ -63,7 +63,7 @@ - + \treeconverter\treeconversion\syntax_tree_visitor.cs if (t.FullName.StartsWith("System.Tuple")) @@ -76,9 +76,9 @@ - + - + \treeconverter\treeconversion\syntax_tree_visitor.cs public override void visit(SyntaxTree.enum_type_definition _enum_type_definition) @@ -89,7 +89,7 @@ - + \TreeConverter\TreeConversion\syntax_tree_visitor.cs if (!is_enum) @@ -100,7 +100,7 @@ - + \TreeConverter\TreeConversion\syntax_tree_visitor.cs public override void visit(SyntaxTree.modern_proc_type _modern_proc_type) @@ -113,9 +113,9 @@ - + - + \treeconverter\symboltable\dsst\symboltable.cs int tn=HashTable.Find(Name); //найдем имя в хеше @@ -126,7 +126,7 @@ - + \TreeConverter\TreeConversion\syntax_tree_visitor.cs public override void visit(SyntaxTree.modern_proc_type _modern_proc_type) @@ -139,9 +139,9 @@ - + - + \TreeConverter\TreeConversion\syntax_tree_visitor.cs public override void visit(SyntaxTree.foreach_stmt _foreach_stmt) @@ -152,11 +152,22 @@ - + \TreeConverter\TreeConversion\syntax_tree_visitor.cs public bool FindIEnumerableElementType(SyntaxTree.foreach_stmt _foreach_stmt, type_node tn, ref type_node elem_type) - public bool FindIEnumerableElementType ( SyntaxTree . foreach_stmt _foreach_stmt , type_node tn , ref type_node elem_type ) + public bool FindIEnumerableElementType ( type_node tn , ref type_node elem_type ) + public class syntax_tree_visitor : SyntaxTree . AbstractVisitor + namespace PascalABCCompiler . TreeConverter + + + + + + \TreeConverter\TreeConversion\syntax_tree_visitor.cs + if (tn is compiled_type_node || tn is compiled_generic_instance_type_node) // Если этот тип зашит в .NET + + public bool FindIEnumerableElementType ( type_node tn , ref type_node elem_type ) public class syntax_tree_visitor : SyntaxTree . AbstractVisitor namespace PascalABCCompiler . TreeConverter @@ -165,9 +176,9 @@ - + - + \treeconverter\lambdaexpressions\lambdaresulttypeinferrer.cs private type_node GetMostCommonType(int kind = 0) @@ -178,7 +189,7 @@ - + \treeconverter\treeconversion\syntax_tree_visitor.cs // SSM 20.07.13 если это - узел с коротким определением функции без типа возвращаемого значения, то вывести этот тип @@ -189,7 +200,7 @@ - + \SyntaxTree\tree\TreeHelper.cs public object RealSemTypeOfResExpr = null; // Result := ex; - семантический тип ex - нужно для лучщего выбора среди перегруженных методов с параметрами-лямбдами @@ -200,7 +211,7 @@ - + \codecompletion\expressionvisitor.cs public override void visit ( assign _assign ) @@ -210,7 +221,7 @@ - + \treeconverter\treeconversion\lambdahelper.cs public class ResultNodesSearcher : SyntaxTree.WalkingVisitorNew @@ -226,7 +237,7 @@ public override void visit ( assign value ) - + \TreeConverter\LambdaExpressions\LambdaResultTypeInferrer.cs internal class LambdaResultTypeInferrer : WalkingVisitorNew @@ -248,7 +259,7 @@ public override void visit ( var_def_statement varStmt ) - + \treeconverter\treeconversion\lambdahelper.cs retType.real_type = new LambdaResultTypeInferrer(funcHeader, procBody, visitor).InferResultType(); @@ -261,7 +272,7 @@ - + \treeconverter\treeconversion\syntax_tree_visitor.cs visit_lambda_header(_procedure_definition.proc_header as SyntaxTree.function_header, _procedure_definition.proc_body); @@ -272,7 +283,7 @@ - + \treeconverter\treeconversion\syntax_tree_visitor.cs hard_node_test_and_visit(_procedure_definition.proc_body); @@ -283,7 +294,7 @@ - + \treeconverter\treeconversion\syntax_tree_visitor.cs hard_node_test_and_visit(_procedure_definition.proc_header); @@ -294,7 +305,7 @@ - + \treeconverter\treeconversion\syntax_tree_visitor.cs if (context.top_function.return_value_type == null) @@ -305,7 +316,7 @@ - + \TreeConverter\TreeConversion\syntax_tree_visitor.cs if (context.top_function.return_value_type == null) @@ -318,9 +329,9 @@ - + - + \treeconverter\treeconversion\syntax_tree_visitor.cs public override void visit(SyntaxTree.question_colon_expression node) @@ -331,7 +342,7 @@ - + \treeconverter\treeconversion\syntax_tree_visitor.cs private void dot_node_as_expression_dot_ident(expression_node en, SyntaxTree.ident id_right, motivation mot, addressed_value syntax_node) @@ -342,7 +353,7 @@ - + \treeconverter\treeconversion\syntax_tree_visitor.cs public override void visit(SyntaxTree.indexer _indexer) @@ -353,7 +364,7 @@ - + \parsers\pascalabcparsernewsaushkin\semanticrules.cs public expression NewVariable(addressed_value variable, expression var_specifiers, LexLocation loc) @@ -366,9 +377,9 @@ - + - + \treeconverter\treeconversion\convertion_data_and_alghoritms.cs public function_node select_function(expressions_list parameters, SymbolInfo functions, location loc, List<SyntaxTree.expression> syntax_nodes_parameters = null) @@ -379,7 +390,7 @@ - + \TreeConverter\TreeConversion\syntax_tree_visitor.cs internal void visit_method_call(SyntaxTree.method_call _method_call) @@ -390,7 +401,7 @@ - + \treeconverter\treeconversion\convertion_data_and_alghoritms.cs function_node inst = generic_convertions.DeduceFunction(func, parameters, @@ -403,9 +414,9 @@ - + - + \treeconverter\treeconversion\syntax_tree_visitor.cs public override void visit(SyntaxTree.procedure_definition _procedure_definition) @@ -416,7 +427,7 @@ - + \treeconverter\treeconversion\syntax_tree_visitor.cs if (ttt is undefined_type) @@ -427,7 +438,7 @@ - + \TreeConverter\TreeConversion\syntax_tree_visitor.cs // SSM 12/04/16 - short func definitions - calc return_value_type @@ -440,9 +451,9 @@ - + - + \TreeConverter\TreeConversion\syntax_tree_visitor.cs public override void visit ( SyntaxTree . function_lambda_definition _function_lambda_definition ) @@ -452,7 +463,7 @@ - + \TreeConverter\TreeConversion\LambdaHelper.cs public static void InferTypesFromVarStmt(type_node leftType, function_lambda_definition lambdaDef, syntax_tree_visitor visitor) @@ -463,7 +474,7 @@ - + \TreeConverter\TreeConversion\syntax_tree_visitor.cs public override void visit(SyntaxTree.assign _assign) @@ -476,9 +487,9 @@ - + - + \Compiler\Compiler.cs CurrentUnit.SyntaxTree = syntaxTreeConvertersController.Convert(CurrentUnit.SyntaxTree) as SyntaxTree.compilation_unit; @@ -489,7 +500,7 @@ - + \Compiler\SemanticTreeConverters\SemanticTreeConvertersController.cs public class SemanticTreeConvertersController @@ -511,7 +522,7 @@ public SemanticTree . IProgramNode Convert ( SemanticTree . IProgramNode ProgramNode ) - + \Compiler\Compiler.cs public SyntaxTreeConvertersController SyntaxTreeConvertersController @@ -522,7 +533,7 @@ - + \Compiler\SyntaxTreeConvertersController\SyntaxTreeConvertersController.cs foreach (ISyntaxTreeConverter SyntaxTreeConverter in syntaxTreeConverters) @@ -535,9 +546,9 @@ - + - + \codecompletion\domconverter.cs if (pattern != null || pattern != "") @@ -548,7 +559,7 @@ - + \visualplugins\languageconverter\source\textformatter.cs _word.Replace(specSymbol, ""); @@ -559,7 +570,7 @@ - + \visualpascalabcnet\formsdesignerbinding\dependecies\src\main\base\project\src\services\refactoringservice\refactoringservice.cs result.OrderBy(node => node.Content.FullyQualifiedName); @@ -570,9 +581,9 @@ - + - + \treeconverter\treeconversion\syntax_tree_visitor.cs if (_pascal_set_constant.values != null && _pascal_set_constant.values != null) @@ -583,7 +594,7 @@ - + \visualpascalabcnet\workbench\runnermanagerhandlers.cs if (File.Exists(pdbFileName) && File.Exists(pdbFileName)) @@ -594,7 +605,7 @@ - + \visualpascalabcnet\formsdesignerbinding\dependecies\src\main\base\project\src\editor\codecompletion\nrefactoryinsightwindowhandler.cs Вот здесь то место, где не учитывается один вариант открывающих скобок Вместо одного из openBracketToken нужно написать openBracesToken @@ -609,9 +620,9 @@ - + - + \treeconverter\systemlib\static_executors.cs if (value >= int.MinValue && value <= int.MaxValue) @@ -622,7 +633,7 @@ - + \treeconverter\systemlib\static_executors.cs if (value >= long.MinValue && value <= long.MaxValue) @@ -633,7 +644,7 @@ - + \NETGenerator\NETGenerator.cs if (pos <= 255) il.Emit(OpCodes.Starg_S, pos); @@ -644,7 +655,7 @@ - + \NETGenerator\NETGenerator.cs if (pos <= 255) il.Emit(OpCodes.Starg_S, pos); @@ -655,7 +666,7 @@ - + \NETGenerator\NETGenerator.cs if (pos <= 255) il.Emit(OpCodes.Ldarga_S, pos); @@ -668,7 +679,7 @@ - + \codecompletion\findreferences.cs Двумя строчками ниже (Здесь сказывается недостаток моего инструмента - если в методе есть две одинаковые строчки - переход осуществляется только на первую, а надо на вторую) @@ -681,7 +692,7 @@ - + \parsertools\syntaxtreevisitors\syntaxtreecomparer.cs 597 и 631 строки в текущей версии else if (left is int64_const) @@ -693,7 +704,7 @@ - + \parsertools\syntaxtreevisitors\syntaxtreecomparer.cs 1599 1611 @@ -709,9 +720,9 @@ - + - + \TreeConverter\TreeConversion\syntax_tree_visitor.cs expression_node bfcint = make_read_call(si, _method_call.parameters, subloc2); @@ -722,7 +733,7 @@ - + \TreeConverter\TreeConversion\syntax_tree_visitor.cs private expression_node make_read_call ( SymbolInfo si , SyntaxTree . expression_list parameters , location loc ) @@ -732,7 +743,7 @@ - + \TreeConverter\TreeConversion\syntax_tree_visitor.cs Это - непонятное место из-за которого происходит ошибка readln_string_file = true; @@ -744,7 +755,7 @@ - + \TreeConverter\TreeConversion\syntax_tree_visitor.cs if (!readln_string_file) @@ -757,7 +768,7 @@ - + \treeconverter\treeconversion\syntax_tree_visitor.cs visit_program_code(_block.program_code); @@ -768,7 +779,7 @@ - + \treeconverter\treeconversion\syntax_tree_visitor.cs if (lab.is_defined) @@ -779,9 +790,9 @@ - + - + \SyntaxVisitors\YieldVisitors\ProcessYieldsCapturedVars.cs public override void visit(procedure_definition pd) @@ -792,7 +803,7 @@ - + \Yield\YieldConversionSyntax\YieldDesugarSyntaxTreeConverter.cs root.visit(new ProcessYieldCapturedVarsVisitor()); @@ -803,9 +814,9 @@ - + - + \syntaxvisitors\yieldvisitors\processyieldscapturedvars.cs public ConstructFiniteAutomata1(block bl) @@ -816,7 +827,7 @@ - + \yield\syntaxvisitors\yieldvisitors\processyieldscapturedvars.cs type_declarations GenClassesForYield(procedure_definition pd, @@ -829,7 +840,7 @@ - + \TreeConverter\TreeConversion\syntax_tree_visitor.cs string Consts__Self = YieldHelpers.YieldConsts.Self; @@ -840,7 +851,7 @@ - + \syntaxvisitors\yieldvisitors\processyieldscapturedvars.cs function_header nfh = ObjectCopier.Clone(fh); @@ -851,7 +862,7 @@ - + \treeconverter\treeconversion\syntax_tree_visitor.cs private Dictionary<Guid, semantic_type_node> _yieldForeachTypeMap = new Dictionary<Guid, semantic_type_node>(); @@ -862,7 +873,7 @@ - + \syntaxvisitors\yieldvisitors\processyieldscapturedvars.cs //InsertHelperMethod(pd, pdCloned); // SSM 13.07.16 - вызов этого метода можно не добавлять @@ -873,9 +884,9 @@ - + - + \treeconverter\treeconversion\syntax_tree_visitor.cs public override void visit(SyntaxTree.yield_unknown_expression_type _unk_expr) @@ -886,7 +897,7 @@ - + \treeconverter\treeconversion\syntax_tree_visitor.cs public override void visit(SyntaxTree.assign _assign) @@ -897,7 +908,7 @@ - + \netgenerator\netgenerator.cs TypeInfo ti = helper.GetTypeReference(value.type); @@ -910,9 +921,9 @@ - + - + \treeconverter\treeconversion\syntax_tree_visitor.cs public override void visit(SyntaxTree.yield_unknown_foreach_type _unk) @@ -923,7 +934,7 @@ - + \syntaxvisitors\yieldvisitors\loweringvisitor.cs stl.Add(new assign(currentIdent, new dot_node(enumeratorIdent, "Current"))); @@ -934,7 +945,7 @@ - + \TreeConverter\TreeConversion\syntax_tree_visitor.cs public override void visit(SyntaxTree.assign _assign) @@ -945,7 +956,7 @@ - + \TreeConverter\TreeConversion\syntax_tree_visitor.cs else if (to.type is compiled_type_node) @@ -956,7 +967,7 @@ - + \TreeConverter\TreeConversion\syntax_tree_visitor.cs public bool FindIEnumerableElementType ( type_node tn , ref type_node elem_type ) @@ -966,7 +977,7 @@ - + \TreeConverter\TreeRealization\generics.cs generic_convertions.all_type_instances.Add(instance); @@ -977,7 +988,7 @@ - + \TreeConverter\TreeRealization\generics.cs if (shouldAddToAllTypeInstances) //lroman// Если зашли сюда при выведении типов параметров лямбды, то тип инстанцироваться может с типом lambda_any_type_node. Поэтому, если выводим типы. То данную инстанцию не добавляем @@ -988,7 +999,7 @@ - + \syntaxvisitors\yieldvisitors\processyieldscapturedvars.cs class ConstructFiniteAutomata @@ -1011,7 +1022,7 @@ - + \syntaxvisitors\yieldvisitors\processyieldscapturedvars.cs ReplaceCapturedVariables(pd, dld.LocalDeletedDefs, out CapturedLocalsNamesMap, out CapturedFormalParamsNamesMap); @@ -1022,7 +1033,7 @@ - + \syntaxvisitors\yieldvisitors\processyieldscapturedvars.cs var pdCloned = ObjectCopier.Clone(pd); @@ -1033,7 +1044,7 @@ - + \syntaxvisitors\YieldVisitors\MarkMethodHasYieldVisitor.cs if (pd.has_yield) // SSM bug fix #219 @@ -1046,9 +1057,9 @@ - + - + \TreeConverter\TreeConversion\convertion_data_and_alghoritms.cs return AddError<function_node>(new SeveralFunctionsCanBeCalled(loc,set_of_possible_functions)); @@ -1059,6 +1070,17 @@ + + \TreeConverter\TreeConversion\convertion_data_and_alghoritms.cs + if (funcs.Count == 2) + + public function_node select_function ( expressions_list parameters , SymbolInfo functions , location loc , List < SyntaxTree . expression > syntax_nodes_parameters = null ) + public class convertion_data_and_alghoritms + namespace PascalABCCompiler . TreeConverter + + + + diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 6d57f0080..c6255aca3 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.1.0.1278' +!define VERSION '3.1.0.1281' diff --git a/SyntaxVisitors/YieldVisitors/MarkMethodHasYieldVisitor.cs b/SyntaxVisitors/YieldVisitors/MarkMethodHasYieldVisitor.cs index 4a1794cdb..b91ec1e55 100644 --- a/SyntaxVisitors/YieldVisitors/MarkMethodHasYieldVisitor.cs +++ b/SyntaxVisitors/YieldVisitors/MarkMethodHasYieldVisitor.cs @@ -110,7 +110,9 @@ namespace SyntaxVisitors public void visit_yield_helper(syntax_tree_node yn) { - var pd = MethodsStack.Peek(); + procedure_definition pd = null; + if (MethodsStack.Count > 0) + pd = MethodsStack.Peek(); if (pd == null) throw new SyntaxVisitorError("ONLY_FUNCTIONS_CAN_CONTAIN_YIELDS", yn.source_context); diff --git a/SyntaxVisitors/YieldVisitors/ReplaceYieldWithLamdasVisitor.cs b/SyntaxVisitors/YieldVisitors/ReplaceYieldWithLamdasVisitor.cs index fd7d321a9..11b15417c 100644 --- a/SyntaxVisitors/YieldVisitors/ReplaceYieldWithLamdasVisitor.cs +++ b/SyntaxVisitors/YieldVisitors/ReplaceYieldWithLamdasVisitor.cs @@ -34,15 +34,29 @@ namespace SyntaxVisitors { var VarIdent = this.NewVarName(); VarIdent.source_context = yn.ex.source_context; - var_statement VS = new var_statement(VarIdent, yn.ex) { source_context = yn.ex.source_context }; - ReplaceStatement(yn, SeqStatements(VS, new yield_node(VarIdent, yn.ex.source_context))); + var_statement vs; + if (yn.ex is nil_const) + vs = new var_statement(VarIdent, new named_type_reference("System.Object"), yn.ex); + else + vs = new var_statement(VarIdent, yn.ex); + vs.source_context = yn.ex.source_context; + ReplaceStatement(yn, SeqStatements(vs, new yield_node(VarIdent, yn.ex.source_context))); } + public override void visit(yield_sequence_node yn) { var VarIdent = this.NewVarName(); VarIdent.source_context = yn.ex.source_context; - var_statement VS = new var_statement(VarIdent, yn.ex) { source_context = yn.ex.source_context }; - ReplaceStatement(yn, SeqStatements(VS, new yield_sequence_node(VarIdent, yn.ex.source_context))); + + var_statement vs; + if (yn.ex is nil_const) + vs = new var_statement(VarIdent, new named_type_reference("System.Object"), yn.ex); + else + vs = new var_statement(VarIdent, yn.ex); + + + //var_statement VS = new var_statement(VarIdent, yn.ex) { source_context = yn.ex.source_context }; + ReplaceStatement(yn, SeqStatements(vs, new yield_sequence_node(VarIdent, yn.ex.source_context))); } } } diff --git a/TestSuite/CompilationSamples/PABCSystem.pas b/TestSuite/CompilationSamples/PABCSystem.pas index 73c47c0e7..917bc28d0 100644 --- a/TestSuite/CompilationSamples/PABCSystem.pas +++ b/TestSuite/CompilationSamples/PABCSystem.pas @@ -2961,7 +2961,7 @@ function ArrNToString(a: System.Array; indexes: array of integer; i: integer): s function StructuredObjectToString(o: Object; n: integer := 0): string; const nmax = 100; - nmax1 = 50; + nmax1 = 30; begin if o is System.Reflection.Pointer then Result := PointerToString(System.Reflection.Pointer.Unbox(o)) diff --git a/TestSuite/errors/err0220.pas b/TestSuite/errors/err0220.pas new file mode 100644 index 000000000..1f45fd2c5 --- /dev/null +++ b/TestSuite/errors/err0220.pas @@ -0,0 +1,3 @@ +begin + yield 1; +end. \ No newline at end of file diff --git a/TestSuite/sum_extension.pas b/TestSuite/sum_extension.pas new file mode 100644 index 000000000..8a11eb6b7 --- /dev/null +++ b/TestSuite/sum_extension.pas @@ -0,0 +1,4 @@ +begin + var t := Range(1,10).Sum(e -> e); + Assert(t=55); +end. \ No newline at end of file diff --git a/TestSuite/yieldnil.pas b/TestSuite/yieldnil.pas new file mode 100644 index 000000000..bf0d8de53 --- /dev/null +++ b/TestSuite/yieldnil.pas @@ -0,0 +1,9 @@ +function f: sequence of object; +begin + yield nil; +end; + +begin + var o: object := nil; + Assert(f.SequenceEqual(Seq(o))); +end. \ No newline at end of file diff --git a/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs b/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs index bef0cad6a..bb75900fb 100644 --- a/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs +++ b/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs @@ -3,6 +3,7 @@ //Некоторые алгоритмы . В основном выбор перегруженного метода. Сильно связан с syntax_tree_visitor. using System; using System.Collections.Generic; +using System.Linq; using PascalABCCompiler.SemanticTree; using PascalABCCompiler.TreeRealization; @@ -2016,7 +2017,8 @@ namespace PascalABCCompiler.TreeConverter set_of_possible_functions.remove(fn); } - foreach (function_node fn in set_of_possible_functions) + // Формирование словаря списков функций с одинаковым значением расстояния + foreach (function_node fn in set_of_possible_functions) { int distance = 0; for (int i = 0; i < parameters.Count; i++) @@ -2025,6 +2027,8 @@ namespace PascalABCCompiler.TreeConverter type_node to = fn.parameters[Math.Min(i,fn.parameters.Count-1)].type; if (fn.parameters[Math.Min(i, fn.parameters.Count - 1)].is_params) to = to.element_type; + // ToDo: необходимо сделать более детальную get_type_distance. + // Сейчас для функциональных параметров она всегда возвращает 1000 distance += get_type_distance(from, to); } @@ -2049,7 +2053,9 @@ namespace PascalABCCompiler.TreeConverter distances[distance] = lst; } } - foreach (int dist in distances.Keys) + foreach (int dist in distances.Keys) // Дистанции упорядочены по возрастанию. Логика тут немного странная: + // если для какой-то минимальной дистанции найдется ровно одна функция, то она и выбирается + // если две и больше - то они пробрасываются и мы переходим к бОльшей дистанции { List funcs = distances[dist]; if (funcs.Count == 1) @@ -2061,6 +2067,60 @@ namespace PascalABCCompiler.TreeConverter convert_function_call_expressions(funcs[0], parameters, tcl); return funcs[0]; } + if (funcs.Count == 2) // SSM - это ужасный способ устранения бага #236 Range(1,10).Sum(e -> e); Для хорошего способа весь код выбора версий функций для делегатов надо переписывать + { + var f1 = funcs[0]; + var f2 = funcs[1]; + + if (f1.parameters.Count == f2.parameters.Count) + { + for (var i=0; i < f1.parameters.Count; i++) + { + var p1 = f1.parameters[i].type; + var p2 = f2.parameters[i].type; + // типы у них должны начинаться на Func, надо посмотреть тип последнего параметра, + // и если это Nullable, то исключить его из рассмотрения + // Напоминаю, что p1 и p2 если это Func, то могут быть + // либо compiled_type_node (List) либо compiled_generic_instance_type_node (List) + + var ctn1 = p1 as compiled_type_node; + if (ctn1 == null) + { + var cgn1 = p1 as compiled_generic_instance_type_node; + if (cgn1 != null) + ctn1 = cgn1.original_generic as compiled_type_node; + } + + var ctn2 = p1 as compiled_type_node; + if (ctn2 == null) + { + var cgn2 = p2 as compiled_generic_instance_type_node; + if (cgn2 != null) + ctn2 = cgn2.original_generic as compiled_type_node; + } + + if (ctn1 == null || ctn2 == null) + continue; + + System.Type ct1 = ctn1.compiled_type; + if (ct1.IsGenericType && ct1.FullName.StartsWith("System.Func")) + { + var c = ct1.GetGenericArguments().Length; + if (c != 0 && ct1.GetGenericArguments().Last().FullName.StartsWith("System.Nullable")) + return f2; + } + + System.Type ct2 = ctn2.compiled_type; + if (ct2.IsGenericType && ct2.FullName.StartsWith("System.Func")) + { + var c = ct2.GetGenericArguments().Length; + if (c != 0 && ct2.GetGenericArguments().Last().FullName.StartsWith("System.Nullable")) + return f1; + } + } + } + + } } return AddError(new SeveralFunctionsCanBeCalled(loc,set_of_possible_functions)); } diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 435843c59..9b011273a 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -16377,15 +16377,13 @@ namespace PascalABCCompiler.TreeConverter // FibGen = class(IEnumerable,IEnumerator): tn = common_type_node, en = compiled_type_node // array of Person: tn = common_type_node { - System.Type ct; + compiled_type_node orig; + if (tn is compiled_type_node) - ct = (tn as compiled_type_node).compiled_type; - else - { - var orig = (tn as compiled_generic_instance_type_node).original_generic as compiled_type_node; - var pars = tn.instance_params; - ct = orig.compiled_type; - } + orig = tn as compiled_type_node; + else orig = (tn as compiled_generic_instance_type_node).original_generic as compiled_type_node; + //var pars = tn.instance_params; + System.Type ct = orig.compiled_type; Type r; var IEnTstring = "System.Collections.Generic.IEnumerable`1"; diff --git a/bin/Lib/PABCRtl.dll b/bin/Lib/PABCRtl.dll index 1828685be6f9062b6a5a5d6e2c116c0361cd9996..743191692fc22ccdc463ab0af46a0b1521ca1f74 100644 GIT binary patch delta 1329 zcmW;M4@?_n7zXewPTRAoZcBu{CcUYt9@Hy&y#BN{P?`#+LFQ2Hg(;gPhC%#7!T%-Y5$)f0i?wd8N2#xWvELdGE^X<$cy)Pt|wCZf-vK z-po|p1kpKIiPCHK9CryRYT4x_oh0_LvMPUZ^ToZT(qQv1v-Ks@OFRW@@it-=Vz@ zomwq)Y4y;py#+nm0a&25K%W+dMOp{+YlmP!>xL`Iy>K;o0A}5D8_$0_ZU%jf9V-n( z8##jVCutNXnQRa(gi!*L^|A$JnPD5b(4dI0v41@_aUFh({w zNE_h@Wy4X*fn(%?6SNtAL;3IwdEqn_!E;mszoSxkkzVzxLFE!v;AD>Wzy;b17wJuS zl^Wp^?T5?s4qTx&xJnVYMqTh<`T#0?1SWAmRQVW8;UOsa1We^In8shh4SWh_unn`c z@)UB=#^#pRj;eppS3CBK`;Z`3?+ll2292_-^3$8Wyg|)?3gMX__HZuA1({g08@pmTbgJ>-XNM`hLEMR z3RyavkfpN=S-MOiOXm;=agS59Lzn1;ZgCiT#D}mz^g*A9S5m}~{o;5KOF($>}N>GezuBr7#6ag5%C3{(+^ezdD{#gJzY0`GLH4z>btTAge7w8#)Ic)ec_lI3Rm8ILs!Y<%QaZ^k^)nzNX%9g zeRsg*P0;mH)4P>+y!Cb{I1=!&%77zq)}(AN_7uB^H*IX6DBC)AbY@4x^ZRS`>a(V3 F!vBDbYH9!g delta 1327 zcmW;M4@{JG7zgk>{&d$1JFqNdr7GF&$J|W=>tQfkjCIh8s0vOlbA}-MiiA_x-)^yZ3g_efN5N z@g85i-xpeRrTI|9w$LXh40V&klls{?eR}=aygo2CA2KrRPMZEVDd~fs{AJ0BiKnO6 zt-l#r^8Butv7FlnzuI3iH18O>{9bHB1TT%gwsyR)E-k0)M9j>IKVI*deI{dN>X*t} z^P7@i`J}RGVSCgY`oB+&9@~6><>2?RrQclhtlv=9Z+-JZk?VGUdiBv8Ufbh`H=Id` zT9^54RQ(ry*Uw)(*>a>uzomY)BQ&tu5jHyR&d)UJ%-ZUsMx8~|A*W~>Ow~&Bj5@2f z8)j%P!7Qy3W@|MtSKAM5+S|~s9e@Rz4;E@o(4ifMixI7GDWV;w-Ls76KNK{9x^Tu! zJi_j6Yn64m~1}&!v zWG7vR74$o-qFGo&3$T{{f-YLla~pLYTE)gox_qO~7qpSWk^Q8>7Gl^&(XgFjVJF4G zZc2o`WP$zk034unI7E-Y5z2z6=m~g+w!(4Bhv%pOUZ9=u5*6he-MXt(g3Sb#!ztPW zr)e*op;zG?)xrgO3og<-aEa>S3N^wtIs|q65e(yxp^-abB!3Ep`(QL5hcP?^H}aP- zfi0M&nNK6TEj)%Lh0noM{t;UFGR)v>FpH;PHva~5`6jgSpU}>Wuz>%8g?tA(_&-?8 zVRrlld^ap-f=)KU3XXwQyb0Fuy|9+=gRTNj!Q$aG=;eo@j~|1LoDKcF1-5V=Y~$^) zoeN z`5cyt>T0>Dt~y1vv_e!rt3>s)MpQp*MfKAqs-GTF{q)K*^ogoxqYUCXeo-ZD5mnDN zQT1#WRnJZt!PRaVg}suW*}CEkA4yh2xN1^Em@ug!OqtXWrcG)HGbS~JIg=W~g2@$_ z+!LO&O`jKt4}>2b#`;~wU1?piwAQrSy!ls~w>hG@_2=-3fRPOLOnrJ_r_B&8fxQmH zQz81ez+jP~>4g-$^Pbh=2*Jm!0uIMngYM}axjVYwt*gFu$-DLaAM}ZLZa5zdRGc-m Gg!~WU%WM(=