bug fix #1280
This commit is contained in:
parent
0549048850
commit
1b0077eab7
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%COREVERSION%=2
|
||||
%REVISION%=1809
|
||||
%MINOR%=4
|
||||
%REVISION%=1812
|
||||
%COREVERSION%=2
|
||||
%MAJOR%=3
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
!define VERSION '3.4.2.1809'
|
||||
!define VERSION '3.4.2.1812'
|
||||
|
|
|
|||
|
|
@ -55,9 +55,10 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
public void ReplaceStatementUsingParent(statement from, IEnumerable<statement> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2181,7 +2181,7 @@ procedure __FinalizeModule__;
|
|||
// DQNToNullable for dot_question_node
|
||||
// -----------------------------------------------------
|
||||
|
||||
function DQNToNullable(v: integer): Nullable<integer>;
|
||||
function DQNToNullable<T>(v: T): Nullable<T>; where T: record;
|
||||
|
||||
implementation
|
||||
|
||||
|
|
@ -11423,9 +11423,9 @@ end;
|
|||
// DQNToNullable for dot_question_node: implementation
|
||||
// -----------------------------------------------------
|
||||
|
||||
function DQNToNullable(v: integer): System.Nullable<integer>;
|
||||
function DQNToNullable<T>(v: T): System.Nullable<T>; where T: record;
|
||||
begin
|
||||
Result := new System.Nullable<integer>(v);
|
||||
Result := new System.Nullable<T>(v);
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
function DQNToNullable<T>(v: T): T; where T: record;
|
||||
{function DQNToNullable<T>(v: T): T; where T: record;
|
||||
begin
|
||||
var res := new System.Nullable<T>(v);
|
||||
Result := res.Value;
|
||||
end;
|
||||
end;}
|
||||
|
||||
begin
|
||||
assert(DQNToNullable(2) = 2);
|
||||
var t := DQNToNullable(2);
|
||||
assert(t.Value = 2);
|
||||
end.
|
||||
13
TestSuite/questionpoint3.pas
Normal file
13
TestSuite/questionpoint3.pas
Normal file
|
|
@ -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.
|
||||
6
TestSuite/questionpoint4.pas
Normal file
6
TestSuite/questionpoint4.pas
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
begin
|
||||
var o: object;
|
||||
if false then
|
||||
raise new Exception( (o?.GetType).ToString);
|
||||
Assert(1=1);
|
||||
end.
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2181,7 +2181,7 @@ procedure __FinalizeModule__;
|
|||
// DQNToNullable for dot_question_node
|
||||
// -----------------------------------------------------
|
||||
|
||||
function DQNToNullable(v: integer): Nullable<integer>;
|
||||
function DQNToNullable<T>(v: T): Nullable<T>; where T: record;
|
||||
|
||||
implementation
|
||||
|
||||
|
|
@ -11423,9 +11423,9 @@ end;
|
|||
// DQNToNullable for dot_question_node: implementation
|
||||
// -----------------------------------------------------
|
||||
|
||||
function DQNToNullable(v: integer): System.Nullable<integer>;
|
||||
function DQNToNullable<T>(v: T): System.Nullable<T>; where T: record;
|
||||
begin
|
||||
Result := new System.Nullable<integer>(v);
|
||||
Result := new System.Nullable<T>(v);
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
|
|
|||
Loading…
Reference in a new issue