diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index c84a80e36..d9f67c2f4 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 = "4"; public const string Build = "2"; - public const string Revision = "1809"; + public const string Revision = "1812"; 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 f5fcc0689..9f6d74994 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ -%COREVERSION%=2 -%REVISION%=1809 %MINOR%=4 +%REVISION%=1812 +%COREVERSION%=2 %MAJOR%=3 diff --git a/Localization/DefaultLang.resources b/Localization/DefaultLang.resources index a23a70453..2c2f49972 100644 Binary files a/Localization/DefaultLang.resources and b/Localization/DefaultLang.resources differ diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index d15dbcdd3..6477f59de 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.4.2.1809' +!define VERSION '3.4.2.1812' diff --git a/SyntaxTree/tree/WalkingVisitorNew.cs b/SyntaxTree/tree/WalkingVisitorNew.cs index eeb98f360..bd420ddc7 100644 --- a/SyntaxTree/tree/WalkingVisitorNew.cs +++ b/SyntaxTree/tree/WalkingVisitorNew.cs @@ -55,9 +55,10 @@ namespace PascalABCCompiler.SyntaxTree public void ReplaceStatementUsingParent(statement from, IEnumerable to, Desc d = Desc.DirectDescendants) { + var fp = from.Parent; // SSM 02.10.18 - запомним, т.к. from.Parent может быть одним из x.Parent foreach (var x in to) - x.Parent = from.Parent; - var sl = from.Parent as statement_list; + x.Parent = fp; + var sl = fp as statement_list; if (sl != null) { sl.ReplaceInList(from, to); @@ -67,7 +68,7 @@ namespace PascalABCCompiler.SyntaxTree var l = new statement_list(); l.AddMany(to); l.source_context = from.source_context; - from.Parent.ReplaceDescendant(from, l, d); + fp.ReplaceDescendant(from, l, d); } } } diff --git a/TestSuite/CompilationSamples/PABCSystem.pas b/TestSuite/CompilationSamples/PABCSystem.pas index 22549005a..4b1ba161e 100644 --- a/TestSuite/CompilationSamples/PABCSystem.pas +++ b/TestSuite/CompilationSamples/PABCSystem.pas @@ -2181,7 +2181,7 @@ procedure __FinalizeModule__; // DQNToNullable for dot_question_node // ----------------------------------------------------- -function DQNToNullable(v: integer): Nullable; +function DQNToNullable(v: T): Nullable; where T: record; implementation @@ -11423,9 +11423,9 @@ end; // DQNToNullable for dot_question_node: implementation // ----------------------------------------------------- -function DQNToNullable(v: integer): System.Nullable; +function DQNToNullable(v: T): System.Nullable; where T: record; begin - Result := new System.Nullable(v); + Result := new System.Nullable(v); end; initialization diff --git a/TestSuite/generics12.pas b/TestSuite/generics12.pas index 6310b3d72..68c86b918 100644 --- a/TestSuite/generics12.pas +++ b/TestSuite/generics12.pas @@ -1,9 +1,10 @@ -function DQNToNullable(v: T): T; where T: record; +{function DQNToNullable(v: T): T; where T: record; begin var res := new System.Nullable(v); Result := res.Value; -end; +end;} begin - assert(DQNToNullable(2) = 2); + var t := DQNToNullable(2); + assert(t.Value = 2); end. \ No newline at end of file diff --git a/TestSuite/questionpoint3.pas b/TestSuite/questionpoint3.pas new file mode 100644 index 000000000..b34c31f17 --- /dev/null +++ b/TestSuite/questionpoint3.pas @@ -0,0 +1,13 @@ +type + TClass = class + fByte: byte := 2; + end; + +begin + var x: TClass := new TClass; + var xxx1 := x=nil ? nil : x.fByte; + var xxx := x?.fByte; + + Assert(xxx.Value=2); + Assert(xxx1.Value=2); +end. \ No newline at end of file diff --git a/TestSuite/questionpoint4.pas b/TestSuite/questionpoint4.pas new file mode 100644 index 000000000..86f536228 --- /dev/null +++ b/TestSuite/questionpoint4.pas @@ -0,0 +1,6 @@ +begin + var o: object; + if false then + raise new Exception( (o?.GetType).ToString); + Assert(1=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 af25c8fc1..c2f741730 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -17284,14 +17284,42 @@ namespace PascalABCCompiler.TreeConverter condition = convertion_data_and_alghoritms.convert_type(condition, SystemLibrary.SystemLibrary.bool_type); expression_node left = convert_strong(node.ret_if_true); expression_node right = convert_strong(node.ret_if_false); + try_convert_typed_expression_to_function_call(ref left); try_convert_typed_expression_to_function_call(ref right); + + if (left is null_const_node && right.type.is_value_type) + { + if (right.type is compiled_type_node) + { + var rt = right.type as compiled_type_node; + if (!rt.compiled_type.IsGenericType || rt.compiled_type.GetGenericTypeDefinition() != typeof(System.Nullable<>)) + { + right = convert_strong(ToNullable(node.ret_if_false)); + } + } + } + else + if (right is null_const_node && left.type.is_value_type) + { + if (left.type is compiled_type_node) + { + var lt = left.type as compiled_type_node; + if (!lt.compiled_type.IsGenericType || lt.compiled_type.GetGenericTypeDefinition() != typeof(System.Nullable<>)) + { + left = convert_strong(ToNullable(node.ret_if_true)); + } + } + } + /*var typeComparisonResult = type_table.compare_types(left.type, right.type); if (typeComparisonResult == type_compare.greater_type) right = convertion_data_and_alghoritms.convert_type(right, left.type); else left = convertion_data_and_alghoritms.convert_type(left, right.type);*/ if (left is null_const_node) + { left = convertion_data_and_alghoritms.convert_type(left, right.type); + } else { delegated_methods del_left = left.type as delegated_methods; @@ -19811,6 +19839,12 @@ namespace PascalABCCompiler.TreeConverter ProcessNode(ex.new_expr); // обойти десахарное выражение - обязательно ProcessNode - visit нельзя! } + public method_call ToNullable(expression e) + { + var dn = new dot_node(new ident("PABCSystem"), new ident("DQNToNullable")); + return new method_call(dn, new expression_list(e), e.source_context); + } + public override void visit(SyntaxTree.sugared_addressed_value av) { if (av.sugared_expr is SyntaxTree.slice_expr) // и slice_expr_question @@ -19827,6 +19861,11 @@ namespace PascalABCCompiler.TreeConverter var dn = new dot_node(new ident("PABCSystem"), new ident("DQNToNullable")); (av.new_addr_value as SyntaxTree.question_colon_expression).ret_if_false = new method_call(dn, new expression_list((av.new_addr_value as SyntaxTree.question_colon_expression).ret_if_false), av.source_context); + + /*var avqce = av.new_addr_value as SyntaxTree.question_colon_expression; + //var dn = new dot_node(new ident("PABCSystem"), new ident("DQNToNullable")); + avqce.ret_if_false = ToNullable(avqce.ret_if_false); + //new method_call(dn, new expression_list(avqce.ret_if_false), av.source_context);*/ } semantic_check_dot_question(av.new_addr_value as SyntaxTree.question_colon_expression); } diff --git a/bin/Lib/PABCSystem.pas b/bin/Lib/PABCSystem.pas index 22549005a..4b1ba161e 100644 --- a/bin/Lib/PABCSystem.pas +++ b/bin/Lib/PABCSystem.pas @@ -2181,7 +2181,7 @@ procedure __FinalizeModule__; // DQNToNullable for dot_question_node // ----------------------------------------------------- -function DQNToNullable(v: integer): Nullable; +function DQNToNullable(v: T): Nullable; where T: record; implementation @@ -11423,9 +11423,9 @@ end; // DQNToNullable for dot_question_node: implementation // ----------------------------------------------------- -function DQNToNullable(v: integer): System.Nullable; +function DQNToNullable(v: T): System.Nullable; where T: record; begin - Result := new System.Nullable(v); + Result := new System.Nullable(v); end; initialization