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 Major = "3";
|
||||||
public const string Minor = "4";
|
public const string Minor = "4";
|
||||||
public const string Build = "2";
|
public const string Build = "2";
|
||||||
public const string Revision = "1809";
|
public const string Revision = "1812";
|
||||||
|
|
||||||
public const string MainVersion = Major + "." + Minor;
|
public const string MainVersion = Major + "." + Minor;
|
||||||
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;
|
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
%COREVERSION%=2
|
|
||||||
%REVISION%=1809
|
|
||||||
%MINOR%=4
|
%MINOR%=4
|
||||||
|
%REVISION%=1812
|
||||||
|
%COREVERSION%=2
|
||||||
%MAJOR%=3
|
%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)
|
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)
|
foreach (var x in to)
|
||||||
x.Parent = from.Parent;
|
x.Parent = fp;
|
||||||
var sl = from.Parent as statement_list;
|
var sl = fp as statement_list;
|
||||||
if (sl != null)
|
if (sl != null)
|
||||||
{
|
{
|
||||||
sl.ReplaceInList(from, to);
|
sl.ReplaceInList(from, to);
|
||||||
|
|
@ -67,7 +68,7 @@ namespace PascalABCCompiler.SyntaxTree
|
||||||
var l = new statement_list();
|
var l = new statement_list();
|
||||||
l.AddMany(to);
|
l.AddMany(to);
|
||||||
l.source_context = from.source_context;
|
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
|
// DQNToNullable for dot_question_node
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
|
|
||||||
function DQNToNullable(v: integer): Nullable<integer>;
|
function DQNToNullable<T>(v: T): Nullable<T>; where T: record;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
|
@ -11423,9 +11423,9 @@ end;
|
||||||
// DQNToNullable for dot_question_node: implementation
|
// 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
|
begin
|
||||||
Result := new System.Nullable<integer>(v);
|
Result := new System.Nullable<T>(v);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
function DQNToNullable<T>(v: T): T; where T: record;
|
{function DQNToNullable<T>(v: T): T; where T: record;
|
||||||
begin
|
begin
|
||||||
var res := new System.Nullable<T>(v);
|
var res := new System.Nullable<T>(v);
|
||||||
Result := res.Value;
|
Result := res.Value;
|
||||||
end;
|
end;}
|
||||||
|
|
||||||
begin
|
begin
|
||||||
assert(DQNToNullable(2) = 2);
|
var t := DQNToNullable(2);
|
||||||
|
assert(t.Value = 2);
|
||||||
end.
|
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);
|
condition = convertion_data_and_alghoritms.convert_type(condition, SystemLibrary.SystemLibrary.bool_type);
|
||||||
expression_node left = convert_strong(node.ret_if_true);
|
expression_node left = convert_strong(node.ret_if_true);
|
||||||
expression_node right = convert_strong(node.ret_if_false);
|
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 left);
|
||||||
try_convert_typed_expression_to_function_call(ref right);
|
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);
|
/*var typeComparisonResult = type_table.compare_types(left.type, right.type);
|
||||||
if (typeComparisonResult == type_compare.greater_type)
|
if (typeComparisonResult == type_compare.greater_type)
|
||||||
right = convertion_data_and_alghoritms.convert_type(right, left.type);
|
right = convertion_data_and_alghoritms.convert_type(right, left.type);
|
||||||
else left = convertion_data_and_alghoritms.convert_type(left, right.type);*/
|
else left = convertion_data_and_alghoritms.convert_type(left, right.type);*/
|
||||||
if (left is null_const_node)
|
if (left is null_const_node)
|
||||||
|
{
|
||||||
left = convertion_data_and_alghoritms.convert_type(left, right.type);
|
left = convertion_data_and_alghoritms.convert_type(left, right.type);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delegated_methods del_left = left.type as delegated_methods;
|
delegated_methods del_left = left.type as delegated_methods;
|
||||||
|
|
@ -19811,6 +19839,12 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
ProcessNode(ex.new_expr); // обойти десахарное выражение - обязательно ProcessNode - visit нельзя!
|
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)
|
public override void visit(SyntaxTree.sugared_addressed_value av)
|
||||||
{
|
{
|
||||||
if (av.sugared_expr is SyntaxTree.slice_expr) // и slice_expr_question
|
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"));
|
var dn = new dot_node(new ident("PABCSystem"), new ident("DQNToNullable"));
|
||||||
(av.new_addr_value as SyntaxTree.question_colon_expression).ret_if_false
|
(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);
|
= 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);
|
semantic_check_dot_question(av.new_addr_value as SyntaxTree.question_colon_expression);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2181,7 +2181,7 @@ procedure __FinalizeModule__;
|
||||||
// DQNToNullable for dot_question_node
|
// DQNToNullable for dot_question_node
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
|
|
||||||
function DQNToNullable(v: integer): Nullable<integer>;
|
function DQNToNullable<T>(v: T): Nullable<T>; where T: record;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
|
@ -11423,9 +11423,9 @@ end;
|
||||||
// DQNToNullable for dot_question_node: implementation
|
// 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
|
begin
|
||||||
Result := new System.Nullable<integer>(v);
|
Result := new System.Nullable<T>(v);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue