diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs
index 4514ab978..ccaed19c8 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 = "5";
public const string Build = "0";
- public const string Revision = "2188";
+ public const string Revision = "2189";
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 af56c93c7..070198d96 100644
--- a/Configuration/Version.defs
+++ b/Configuration/Version.defs
@@ -1,4 +1,4 @@
-%COREVERSION%=0
-%REVISION%=2188
%MINOR%=5
+%REVISION%=2189
+%COREVERSION%=0
%MAJOR%=3
diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh
index 5384fe5ae..2434e9285 100644
--- a/ReleaseGenerators/PascalABCNET_version.nsh
+++ b/ReleaseGenerators/PascalABCNET_version.nsh
@@ -1 +1 @@
-!define VERSION '3.5.0.2188'
+!define VERSION '3.5.0.2189'
diff --git a/SyntaxTree/tree/TreeHelper.cs b/SyntaxTree/tree/TreeHelper.cs
index 88149207b..3c23c6d4a 100644
--- a/SyntaxTree/tree/TreeHelper.cs
+++ b/SyntaxTree/tree/TreeHelper.cs
@@ -1720,6 +1720,10 @@ namespace PascalABCCompiler.SyntaxTree
{
return new SyntaxTree.dot_node(this, id, sc);
}
+ ///
+ /// Сервисное поле для реализации механизма ?. Оно - типа question_colon_expression
+ ///
+ public object ExprToQCE = null;
}
public partial class expression
diff --git a/SyntaxVisitors/SugarVisitors/QuestionPointDesugarVisitor.cs b/SyntaxVisitors/SugarVisitors/QuestionPointDesugarVisitor.cs
index be64919b3..ce9168364 100644
--- a/SyntaxVisitors/SugarVisitors/QuestionPointDesugarVisitor.cs
+++ b/SyntaxVisitors/SugarVisitors/QuestionPointDesugarVisitor.cs
@@ -163,19 +163,28 @@ namespace SyntaxVisitors.SugarVisitors
if (st == null)
throw new SyntaxVisitorError("?._CANNOT_BE_IN_THIS_CONTEXT", dqn.source_context);
var tname = "#dqn_temp" + UniqueNumStr();
- var tt = new var_statement(new ident(tname), dqn.left, dqn.source_context);
+
+ dot_question_node rif = null;
+ var qce = ConvertToQCE1(dqn, tname);
+ if (qce.ret_if_false is dot_question_node dn)
+ {
+ rif = dn;
+ var expr = new question_colon_expression(qce.condition, qce.ret_if_true, rif.left);
+ rif.left.ExprToQCE = expr;
+ }
+ var sug = sugared_addressed_value.NewP(dqn, qce, dqn.source_context);
+ ReplaceUsingParent(dqn, sug);
+ //Replace(dqn, sug); // Этот не подходит!
+
+ var dl = (dqn.left.ExprToQCE == null ? dqn.left : dqn.left.ExprToQCE) as addressed_value;
+ var tt = new var_statement(new ident(tname), dl, dqn.source_context);
tt.var_def.Parent = tt;
var l = new List();
l.Add(tt);
l.Add(st as statement);
- var qce = ConvertToQCE1(dqn, tname);
- var sug = sugared_addressed_value.NewP(dqn, qce, dqn.source_context);
- //ReplaceUsingParent(dqn, sug);
- Replace(dqn, sug); // SSM 30/09/18
- visit(qce);
-
ReplaceStatementUsingParent(st as statement, l);
+ visit(qce);
visit(tt);
}
/*public override void visit(dot_question_node dqn)
diff --git a/TestSuite/CompilationSamples/graph3d.pas b/TestSuite/CompilationSamples/graph3d.pas
index 078d4047f..226d02948 100644
--- a/TestSuite/CompilationSamples/graph3d.pas
+++ b/TestSuite/CompilationSamples/graph3d.pas
@@ -577,6 +577,10 @@ type
function AnimRotateAt(axis: Vector3D; angle: real; center: Point3D; seconds: real; Completed: procedure): AnimationBase;
/// Возвращает анимацию поворота объекта вокруг вектора axis, направленного из точки center, на величину angle за seconds секунд
function AnimRotateAt(axis: Vector3D; angle: real; center: Point3D; seconds: real := 1): AnimationBase := AnimRotateAt(axis,angle,center,seconds,nil);
+ /// Возвращает анимацию поворота объекта вокруг вектора axis, направленного из точки center, на величину angle за seconds секунд. В конце анимации выполняется процедура Completed
+ function AnimRotateAtAbsolute(axis: Vector3D; angle: real; center: Point3D; seconds: real; Completed: procedure): AnimationBase;
+ /// Возвращает анимацию поворота объекта вокруг вектора axis, направленного из точки center, на величину angle за seconds секунд
+ function AnimRotateAtAbsolute(axis: Vector3D; angle: real; center: Point3D; seconds: real := 1): AnimationBase := AnimRotateAtAbsolute(axis,angle,center,seconds,nil);
/// Клонирует 3D-объект
function Clone: Object3D := Invoke&(CloneT);
@@ -673,6 +677,8 @@ type
public
/// Добавить дочерний подобъект
procedure AddChild(obj: Object3D) := Invoke(AddT, obj);
+ /// Удалить дочерний подобъект
+ procedure RemoveChild(obj: Object3D) := Invoke(RemoveT, obj);
/// i-тый дочерний подобъект
property Items[i: integer]: Object3D read GetObj; default;
@@ -767,6 +773,14 @@ type
foreach var xx in lst do
AddChild(xx);
end;
+ public
+ procedure UnGroup;
+ begin
+ for var i := l.Count-1 downto 0 do
+ begin
+ RemoveChild(l[i]);
+ end;
+ end;
/// ВОзвращает клон группы 3D-объектов
function Clone := (inherited Clone) as Group3D;
@@ -1282,8 +1296,10 @@ type
begin
el := new RotateTransform3D();
el.Rotation := new AxisAngleRotation3D();
-
- Element.transfgroup.Children.Insert(0,el); // До основной матрицы, связанной с поворотом
+
+ if Absolute then
+ Element.transfgroup.Children.Add(el) // После основной матрицы, связанной с поворотом
+ else Element.transfgroup.Children.Insert(0,el); // До основной матрицы, связанной с поворотом
var rottransform := el;
rottransform.CenterX := center.x;
rottransform.CenterY := center.y;
@@ -1309,9 +1325,20 @@ type
(vx, vy, vz, angle, center) := (vvx, vvy, vvz, a, c)
end;
public
+ auto property Absolute: boolean;
function Clone: AnimationBase; override := new RotateAtAnimation(Element,Seconds,vx,vy,vz,angle,center,nil);
end;
+ RotateAtAbsoluteAnimation = class(RotateAtAnimation)
+ public
+ constructor(e: Object3D; sec: real; vvx, vvy, vvz, a: real; c: Point3D; Completed: procedure := nil);
+ begin
+ inherited Create(e,sec,vvx,vvy,vvz,a,c,Completed);
+ Absolute := True;
+ end;
+ function Clone: AnimationBase; override := new RotateAtAbsoluteAnimation(Element,Seconds,vx,vy,vz,angle,center,nil);
+ end;
+
CompositeAnimation = class(AnimationBase)
private
ll: List;
@@ -2696,6 +2723,8 @@ function Object3D.AnimRotate(vx, vy, vz, angle, seconds: real; Completed: proced
function Object3D.AnimRotateAt(axis: Vector3D; angle: real; center: Point3D; seconds: real; Completed: procedure) := new RotateAtAnimation(Self, seconds, axis.X, axis.y, axis.z, angle, center, Completed);
+function Object3D.AnimRotateAtAbsolute(axis: Vector3D; angle: real; center: Point3D; seconds: real; Completed: procedure) := new RotateAtAbsoluteAnimation(Self, seconds, axis.X, axis.y, axis.z, angle, center, Completed);
+
procedure Object3D.AddToObject3DList := Object3DList.Add(Self);
procedure Object3D.DeleteFromObject3DList;
diff --git a/TestSuite/dqn_2.pas b/TestSuite/dqn_2.pas
new file mode 100644
index 000000000..74e69fed7
--- /dev/null
+++ b/TestSuite/dqn_2.pas
@@ -0,0 +1,17 @@
+type A = class
+ x: A;
+ o: object := 999;
+ constructor Create;
+ begin
+ x := Self;
+ end;
+ procedure p;
+ begin
+ end;
+end;
+
+begin
+ var q: A := new A;
+ var ob := q?.x?.o;
+ Assert(integer(ob) = 999);
+end.
\ No newline at end of file
diff --git a/bin/Lib/Graph3D.pas b/bin/Lib/Graph3D.pas
index 078d4047f..226d02948 100644
--- a/bin/Lib/Graph3D.pas
+++ b/bin/Lib/Graph3D.pas
@@ -577,6 +577,10 @@ type
function AnimRotateAt(axis: Vector3D; angle: real; center: Point3D; seconds: real; Completed: procedure): AnimationBase;
/// Возвращает анимацию поворота объекта вокруг вектора axis, направленного из точки center, на величину angle за seconds секунд
function AnimRotateAt(axis: Vector3D; angle: real; center: Point3D; seconds: real := 1): AnimationBase := AnimRotateAt(axis,angle,center,seconds,nil);
+ /// Возвращает анимацию поворота объекта вокруг вектора axis, направленного из точки center, на величину angle за seconds секунд. В конце анимации выполняется процедура Completed
+ function AnimRotateAtAbsolute(axis: Vector3D; angle: real; center: Point3D; seconds: real; Completed: procedure): AnimationBase;
+ /// Возвращает анимацию поворота объекта вокруг вектора axis, направленного из точки center, на величину angle за seconds секунд
+ function AnimRotateAtAbsolute(axis: Vector3D; angle: real; center: Point3D; seconds: real := 1): AnimationBase := AnimRotateAtAbsolute(axis,angle,center,seconds,nil);
/// Клонирует 3D-объект
function Clone: Object3D := Invoke&(CloneT);
@@ -673,6 +677,8 @@ type
public
/// Добавить дочерний подобъект
procedure AddChild(obj: Object3D) := Invoke(AddT, obj);
+ /// Удалить дочерний подобъект
+ procedure RemoveChild(obj: Object3D) := Invoke(RemoveT, obj);
/// i-тый дочерний подобъект
property Items[i: integer]: Object3D read GetObj; default;
@@ -767,6 +773,14 @@ type
foreach var xx in lst do
AddChild(xx);
end;
+ public
+ procedure UnGroup;
+ begin
+ for var i := l.Count-1 downto 0 do
+ begin
+ RemoveChild(l[i]);
+ end;
+ end;
/// ВОзвращает клон группы 3D-объектов
function Clone := (inherited Clone) as Group3D;
@@ -1282,8 +1296,10 @@ type
begin
el := new RotateTransform3D();
el.Rotation := new AxisAngleRotation3D();
-
- Element.transfgroup.Children.Insert(0,el); // До основной матрицы, связанной с поворотом
+
+ if Absolute then
+ Element.transfgroup.Children.Add(el) // После основной матрицы, связанной с поворотом
+ else Element.transfgroup.Children.Insert(0,el); // До основной матрицы, связанной с поворотом
var rottransform := el;
rottransform.CenterX := center.x;
rottransform.CenterY := center.y;
@@ -1309,9 +1325,20 @@ type
(vx, vy, vz, angle, center) := (vvx, vvy, vvz, a, c)
end;
public
+ auto property Absolute: boolean;
function Clone: AnimationBase; override := new RotateAtAnimation(Element,Seconds,vx,vy,vz,angle,center,nil);
end;
+ RotateAtAbsoluteAnimation = class(RotateAtAnimation)
+ public
+ constructor(e: Object3D; sec: real; vvx, vvy, vvz, a: real; c: Point3D; Completed: procedure := nil);
+ begin
+ inherited Create(e,sec,vvx,vvy,vvz,a,c,Completed);
+ Absolute := True;
+ end;
+ function Clone: AnimationBase; override := new RotateAtAbsoluteAnimation(Element,Seconds,vx,vy,vz,angle,center,nil);
+ end;
+
CompositeAnimation = class(AnimationBase)
private
ll: List;
@@ -2696,6 +2723,8 @@ function Object3D.AnimRotate(vx, vy, vz, angle, seconds: real; Completed: proced
function Object3D.AnimRotateAt(axis: Vector3D; angle: real; center: Point3D; seconds: real; Completed: procedure) := new RotateAtAnimation(Self, seconds, axis.X, axis.y, axis.z, angle, center, Completed);
+function Object3D.AnimRotateAtAbsolute(axis: Vector3D; angle: real; center: Point3D; seconds: real; Completed: procedure) := new RotateAtAbsoluteAnimation(Self, seconds, axis.X, axis.y, axis.z, angle, center, Completed);
+
procedure Object3D.AddToObject3DList := Object3DList.Add(Self);
procedure Object3D.DeleteFromObject3DList;