mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-03 16:17:21 +01:00
pastojs: helper: default array property
git-svn-id: trunk@41252 -
This commit is contained in:
parent
9a06e90b47
commit
15ec036a69
@ -8711,33 +8711,35 @@ var
|
|||||||
aResolver:=AContext.Resolver;
|
aResolver:=AContext.Resolver;
|
||||||
Call:=nil;
|
Call:=nil;
|
||||||
try
|
try
|
||||||
|
// find getter/setter
|
||||||
case AContext.Access of
|
case AContext.Access of
|
||||||
caAssign:
|
caAssign:
|
||||||
begin
|
|
||||||
AccessEl:=aResolver.GetPasPropertySetter(Prop);
|
AccessEl:=aResolver.GetPasPropertySetter(Prop);
|
||||||
|
caRead:
|
||||||
|
AccessEl:=aResolver.GetPasPropertyGetter(Prop);
|
||||||
|
else
|
||||||
|
RaiseNotSupported(El,AContext,20170213213317);
|
||||||
|
end;
|
||||||
if IsJSBracketAccessorAndConvert(Prop,AccessEl,AContext,true) then
|
if IsJSBracketAccessorAndConvert(Prop,AccessEl,AContext,true) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
// create call
|
||||||
if aResolver.IsHelperMethod(AccessEl) then
|
if aResolver.IsHelperMethod(AccessEl) then
|
||||||
|
begin
|
||||||
|
if CheckPath then
|
||||||
Call:=CreateCallHelperMethod(TPasProcedure(AccessEl),El.Value,AContext)
|
Call:=CreateCallHelperMethod(TPasProcedure(AccessEl),El.Value,AContext)
|
||||||
|
else
|
||||||
|
Call:=CreateCallHelperMethod(TPasProcedure(AccessEl),El,AContext)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
Call:=CreateCallExpression(El);
|
Call:=CreateCallExpression(El);
|
||||||
|
|
||||||
|
if AContext.Access=caAssign then
|
||||||
|
begin
|
||||||
AssignContext:=AContext.AccessContext as TAssignContext;
|
AssignContext:=AContext.AccessContext as TAssignContext;
|
||||||
AssignContext.PropertyEl:=Prop;
|
AssignContext.PropertyEl:=Prop;
|
||||||
AssignContext.Call:=Call;
|
AssignContext.Call:=Call;
|
||||||
end;
|
end;
|
||||||
caRead:
|
|
||||||
begin
|
|
||||||
AccessEl:=aResolver.GetPasPropertyGetter(Prop);
|
|
||||||
if IsJSBracketAccessorAndConvert(Prop,AccessEl,AContext,true) then
|
|
||||||
exit;
|
|
||||||
if aResolver.IsHelperMethod(AccessEl) then
|
|
||||||
Call:=CreateCallHelperMethod(TPasProcedure(AccessEl),El.Value,AContext)
|
|
||||||
else
|
|
||||||
Call:=CreateCallExpression(El);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
RaiseNotSupported(El,AContext,20170213213317);
|
|
||||||
end;
|
|
||||||
|
|
||||||
if CheckPath and (Call.Expr=nil) then
|
if CheckPath and (Call.Expr=nil) then
|
||||||
if aResolver.IsNameExpr(El.Value) then
|
if aResolver.IsNameExpr(El.Value) then
|
||||||
@ -8839,27 +8841,29 @@ var
|
|||||||
Left, Right: TJSElement;
|
Left, Right: TJSElement;
|
||||||
OldAccess: TCtxAccess;
|
OldAccess: TCtxAccess;
|
||||||
AccessEl, SetAccessEl: TPasElement;
|
AccessEl, SetAccessEl: TPasElement;
|
||||||
|
aResolver: TPas2JSResolver;
|
||||||
begin
|
begin
|
||||||
|
aResolver:=AContext.Resolver;
|
||||||
case AContext.Access of
|
case AContext.Access of
|
||||||
caAssign:
|
caAssign:
|
||||||
begin
|
begin
|
||||||
AccessEl:=AContext.Resolver.GetPasPropertySetter(Prop);
|
AccessEl:=aResolver.GetPasPropertySetter(Prop);
|
||||||
if IsJSBracketAccessorAndConvert(Prop,AccessEl,AContext,false) then
|
if IsJSBracketAccessorAndConvert(Prop,AccessEl,AContext,false) then
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
caRead:
|
caRead:
|
||||||
begin
|
begin
|
||||||
AccessEl:=AContext.Resolver.GetPasPropertyGetter(Prop);
|
AccessEl:=aResolver.GetPasPropertyGetter(Prop);
|
||||||
if IsJSBracketAccessorAndConvert(Prop,AccessEl,AContext,false) then
|
if IsJSBracketAccessorAndConvert(Prop,AccessEl,AContext,false) then
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
caByReference:
|
caByReference:
|
||||||
begin
|
begin
|
||||||
AccessEl:=AContext.Resolver.GetPasPropertyGetter(Prop);
|
AccessEl:=aResolver.GetPasPropertyGetter(Prop);
|
||||||
SetAccessEl:=AContext.Resolver.GetPasPropertySetter(Prop);
|
SetAccessEl:=aResolver.GetPasPropertySetter(Prop);
|
||||||
if AContext.Resolver.IsExternalBracketAccessor(AccessEl) then
|
if aResolver.IsExternalBracketAccessor(AccessEl) then
|
||||||
begin
|
begin
|
||||||
if AContext.Resolver.IsExternalBracketAccessor(SetAccessEl) then
|
if aResolver.IsExternalBracketAccessor(SetAccessEl) then
|
||||||
begin
|
begin
|
||||||
// read and write are brackets -> easy
|
// read and write are brackets -> easy
|
||||||
if not IsJSBracketAccessorAndConvert(Prop,AccessEl,AContext,false) then
|
if not IsJSBracketAccessorAndConvert(Prop,AccessEl,AContext,false) then
|
||||||
@ -8873,6 +8877,12 @@ var
|
|||||||
RaiseNotSupported(El,AContext,20170402233834);
|
RaiseNotSupported(El,AContext,20170402233834);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if aResolver.IsHelperMethod(AccessEl) then
|
||||||
|
begin
|
||||||
|
ConvertIndexedProperty(Prop,AContext,false);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
DotContext:=nil;
|
DotContext:=nil;
|
||||||
Left:=nil;
|
Left:=nil;
|
||||||
Right:=nil;
|
Right:=nil;
|
||||||
@ -16977,6 +16987,7 @@ begin
|
|||||||
SelfScope:=nil;
|
SelfScope:=nil;
|
||||||
PosEl:=Expr;
|
PosEl:=Expr;
|
||||||
Ref:=nil;
|
Ref:=nil;
|
||||||
|
Prop:=nil;
|
||||||
Left:=nil;
|
Left:=nil;
|
||||||
SelfJS:=nil;
|
SelfJS:=nil;
|
||||||
Call:=nil;
|
Call:=nil;
|
||||||
@ -17021,6 +17032,17 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
else if Expr is TParamsExpr then
|
||||||
|
begin
|
||||||
|
PosEl:=Expr;
|
||||||
|
if not (Expr.CustomData is TResolvedReference) then
|
||||||
|
RaiseNotSupported(Expr,AContext,20190208105144);
|
||||||
|
Ref:=TResolvedReference(PosEl.CustomData);
|
||||||
|
if Ref.Declaration.ClassType<>TPasProperty then
|
||||||
|
RaiseNotSupported(Expr,AContext,20190208105222);
|
||||||
|
Left:=TParamsExpr(Expr).Value;
|
||||||
|
aResolver.ComputeElement(Left,LeftResolved,[]);
|
||||||
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
RaiseNotSupported(Expr,AContext,20190201163210);
|
RaiseNotSupported(Expr,AContext,20190201163210);
|
||||||
@ -17029,7 +17051,6 @@ begin
|
|||||||
|
|
||||||
LoTypeEl:=LeftResolved.LoTypeEl;
|
LoTypeEl:=LeftResolved.LoTypeEl;
|
||||||
IdentEl:=LeftResolved.IdentEl;
|
IdentEl:=LeftResolved.IdentEl;
|
||||||
Prop:=nil;
|
|
||||||
IsConstructorNormalCall:=false;
|
IsConstructorNormalCall:=false;
|
||||||
if Ref<>nil then
|
if Ref<>nil then
|
||||||
begin
|
begin
|
||||||
|
|||||||
@ -639,7 +639,8 @@ type
|
|||||||
Procedure TestClassHelper_InheritedObjFPC;
|
Procedure TestClassHelper_InheritedObjFPC;
|
||||||
Procedure TestClassHelper_Property;
|
Procedure TestClassHelper_Property;
|
||||||
Procedure TestClassHelper_Property_Array;
|
Procedure TestClassHelper_Property_Array;
|
||||||
//Procedure TestClassHelper_Property_Array_Default;
|
Procedure TestClassHelper_Property_Array_Default;
|
||||||
|
Procedure TestClassHelper_Property_Array_DefaultDefault;
|
||||||
// todo: TestClassHelper_ClassProperty static/nonstatic
|
// todo: TestClassHelper_ClassProperty static/nonstatic
|
||||||
// todo: TestClassHelper_ClassProperty_Array
|
// todo: TestClassHelper_ClassProperty_Array
|
||||||
// todo: TestClassHelper_Overload
|
// todo: TestClassHelper_Overload
|
||||||
@ -19655,6 +19656,133 @@ begin
|
|||||||
'']));
|
'']));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestModule.TestClassHelper_Property_Array_Default;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'type',
|
||||||
|
' TObject = class',
|
||||||
|
' function GetSpeed(Index: boolean): word;',
|
||||||
|
' procedure SetSpeed(Index: boolean; Value: word);',
|
||||||
|
' end;',
|
||||||
|
' TObjHelper = class helper for TObject',
|
||||||
|
' property Speed[Index: boolean]: word read GetSpeed write SetSpeed; default;',
|
||||||
|
' end;',
|
||||||
|
' TBird = class',
|
||||||
|
' end;',
|
||||||
|
' TBirdHelper = class helper for TBird',
|
||||||
|
' function GetSize(Index: word): boolean;',
|
||||||
|
' procedure SetSize(Index: word; Value: boolean);',
|
||||||
|
' property Size[Index: word]: boolean read GetSize write SetSize; default;',
|
||||||
|
' end;',
|
||||||
|
'function Tobject.GetSpeed(Index: boolean): word;',
|
||||||
|
'begin',
|
||||||
|
' Self[true]:=Self[false]+1;',
|
||||||
|
'end;',
|
||||||
|
'procedure Tobject.SetSpeed(Index: boolean; Value: word);',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'function TBirdHelper.GetSize(Index: word): boolean;',
|
||||||
|
'begin',
|
||||||
|
' Self[1]:=not Self[2];',
|
||||||
|
'end;',
|
||||||
|
'procedure TBirdHelper.SetSize(Index: word; Value: boolean);',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'var',
|
||||||
|
' o: TObject;',
|
||||||
|
' b: TBird;',
|
||||||
|
'begin',
|
||||||
|
' o[true]:=o[false]+1;',
|
||||||
|
' b[3]:=not b[4];',
|
||||||
|
'']);
|
||||||
|
ConvertProgram;
|
||||||
|
CheckSource('TestClassHelper_Property_Array_Default',
|
||||||
|
LinesToStr([ // statements
|
||||||
|
'rtl.createClass($mod, "TObject", null, function () {',
|
||||||
|
' this.$init = function () {',
|
||||||
|
' };',
|
||||||
|
' this.$final = function () {',
|
||||||
|
' };',
|
||||||
|
' this.GetSpeed = function (Index) {',
|
||||||
|
' var Result = 0;',
|
||||||
|
' this.SetSpeed(true, this.GetSpeed(false) + 1);',
|
||||||
|
' return Result;',
|
||||||
|
' };',
|
||||||
|
' this.SetSpeed = function (Index, Value) {',
|
||||||
|
' };',
|
||||||
|
'});',
|
||||||
|
'rtl.createHelper($mod, "TObjHelper", null, function () {',
|
||||||
|
'});',
|
||||||
|
'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
|
||||||
|
'});',
|
||||||
|
'rtl.createHelper($mod, "TBirdHelper", null, function () {',
|
||||||
|
' this.GetSize = function (Index) {',
|
||||||
|
' var Result = false;',
|
||||||
|
' $mod.TBirdHelper.SetSize.apply(this, 1, !$mod.TBirdHelper.GetSize.apply(this, 2));',
|
||||||
|
' return Result;',
|
||||||
|
' };',
|
||||||
|
' this.SetSize = function (Index, Value) {',
|
||||||
|
' };',
|
||||||
|
'});',
|
||||||
|
'this.o = null;',
|
||||||
|
'this.b = null;',
|
||||||
|
'']),
|
||||||
|
LinesToStr([ // $mod.$main
|
||||||
|
'$mod.o.SetSpeed(true, $mod.o.GetSpeed(false) + 1);',
|
||||||
|
'$mod.TBirdHelper.SetSize.apply($mod.b, 3, !$mod.TBirdHelper.GetSize.apply($mod.b, 4));',
|
||||||
|
'']));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestModule.TestClassHelper_Property_Array_DefaultDefault;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'type',
|
||||||
|
' TObject = class',
|
||||||
|
' end;',
|
||||||
|
' TObjHelper = class helper for TObject',
|
||||||
|
' function GetItems(Index: word): TObject;',
|
||||||
|
' procedure SetItems(Index: word; Value: TObject);',
|
||||||
|
' property Items[Index: word]: TObject read GetItems write SetItems; default;',
|
||||||
|
' end;',
|
||||||
|
'function Tobjhelper.GetItems(Index: word): TObject;',
|
||||||
|
'begin',
|
||||||
|
' Self[1][2]:=Self[3][4];',
|
||||||
|
'end;',
|
||||||
|
'procedure Tobjhelper.SetItems(Index: word; Value: TObject);',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'var',
|
||||||
|
' o: TObject;',
|
||||||
|
'begin',
|
||||||
|
' o[1][2]:=o[3][4];',
|
||||||
|
'']);
|
||||||
|
ConvertProgram;
|
||||||
|
CheckSource('TestClassHelper_Property_Array_DefaultDefault',
|
||||||
|
LinesToStr([ // statements
|
||||||
|
'rtl.createClass($mod, "TObject", null, function () {',
|
||||||
|
' this.$init = function () {',
|
||||||
|
' };',
|
||||||
|
' this.$final = function () {',
|
||||||
|
' };',
|
||||||
|
'});',
|
||||||
|
'rtl.createHelper($mod, "TObjHelper", null, function () {',
|
||||||
|
' this.GetItems = function (Index) {',
|
||||||
|
' var Result = null;',
|
||||||
|
' $mod.TObjHelper.SetItems.apply($mod.TObjHelper.GetItems.apply(this, 1), 2, $mod.TObjHelper.GetItems.apply($mod.TObjHelper.GetItems.apply(this, 3), 4));',
|
||||||
|
' return Result;',
|
||||||
|
' };',
|
||||||
|
' this.SetItems = function (Index, Value) {',
|
||||||
|
' };',
|
||||||
|
'});',
|
||||||
|
'this.o = null;',
|
||||||
|
'']),
|
||||||
|
LinesToStr([ // $mod.$main
|
||||||
|
'$mod.TObjHelper.SetItems.apply($mod.TObjHelper.GetItems.apply($mod.o, 1), 2, $mod.TObjHelper.GetItems.apply($mod.TObjHelper.GetItems.apply($mod.o, 3), 4));',
|
||||||
|
'']));
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestModule.TestProcType;
|
procedure TTestModule.TestProcType;
|
||||||
begin
|
begin
|
||||||
StartProgram(false);
|
StartProgram(false);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user