mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-03 20:50:39 +02:00
pastojs: record const
git-svn-id: trunk@38869 -
This commit is contained in:
parent
70b4a4b9a5
commit
01ccfbcf61
@ -81,6 +81,8 @@ Works:
|
|||||||
- clone set member
|
- clone set member
|
||||||
- clone when passing as argument
|
- clone when passing as argument
|
||||||
- equal, not equal
|
- equal, not equal
|
||||||
|
- const
|
||||||
|
- array of record-const
|
||||||
- classes
|
- classes
|
||||||
- declare using createClass
|
- declare using createClass
|
||||||
- constructor
|
- constructor
|
||||||
@ -373,7 +375,6 @@ Not in Version 1.0:
|
|||||||
- sets
|
- sets
|
||||||
- set of char, boolean, integer range, char range, enum range
|
- set of char, boolean, integer range, char range, enum range
|
||||||
- call array of proc element without ()
|
- call array of proc element without ()
|
||||||
- record const
|
|
||||||
- enums with custom values
|
- enums with custom values
|
||||||
- library
|
- library
|
||||||
- constref
|
- constref
|
||||||
@ -1193,7 +1194,7 @@ type
|
|||||||
RHS: TPasExpr); override;
|
RHS: TPasExpr); override;
|
||||||
function HasStaticArrayCloneFunc(Arr: TPasArrayType): boolean;
|
function HasStaticArrayCloneFunc(Arr: TPasArrayType): boolean;
|
||||||
function IsTGUID(TypeEl: TPasRecordType): boolean; override;
|
function IsTGUID(TypeEl: TPasRecordType): boolean; override;
|
||||||
function GetAssignGUIDString(TypeEl: TPasRecordType; Expr: TPasExpr; out GUID: TGUID): boolean;
|
function GetAssignGUIDString(TypeEl: TPasRecordType; Expr: TPasExpr; out GUID: TGuid): boolean;
|
||||||
// CustomData
|
// CustomData
|
||||||
function GetElementData(El: TPasElementBase;
|
function GetElementData(El: TPasElementBase;
|
||||||
DataClass: TPas2JsElementDataClass): TPas2JsElementData; virtual;
|
DataClass: TPas2JsElementDataClass): TPas2JsElementData; virtual;
|
||||||
@ -4174,7 +4175,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TPas2JSResolver.GetAssignGUIDString(TypeEl: TPasRecordType;
|
function TPas2JSResolver.GetAssignGUIDString(TypeEl: TPasRecordType;
|
||||||
Expr: TPasExpr; out GUID: TGUID): boolean;
|
Expr: TPasExpr; out GUID: TGuid): boolean;
|
||||||
var
|
var
|
||||||
Value: TResEvalValue;
|
Value: TResEvalValue;
|
||||||
GUIDStr: String;
|
GUIDStr: String;
|
||||||
@ -9784,23 +9785,60 @@ end;
|
|||||||
|
|
||||||
function TPasToJSConverter.ConvertRecordValues(El: TRecordValues;
|
function TPasToJSConverter.ConvertRecordValues(El: TRecordValues;
|
||||||
AContext: TConvertContext): TJSElement;
|
AContext: TConvertContext): TJSElement;
|
||||||
|
var
|
||||||
Var
|
ObjLit: TJSObjectLiteral;
|
||||||
R : TJSObjectLiteral;
|
i: Integer;
|
||||||
I : Integer;
|
RecFields: TRecordValuesItemArray;
|
||||||
RVI : TRecordValuesItem;
|
Field: PRecordValuesItem;
|
||||||
rel : TJSObjectLiteralElement;
|
Ref: TResolvedReference;
|
||||||
|
Member: TPasVariable;
|
||||||
|
NewMemE: TJSNewMemberExpression;
|
||||||
|
aResolver: TPas2JSResolver;
|
||||||
|
ResolvedEl: TPasResolverResult;
|
||||||
|
RecType: TPasRecordType;
|
||||||
|
ok: Boolean;
|
||||||
|
ObjLitEl: TJSObjectLiteralElement;
|
||||||
begin
|
begin
|
||||||
R:=TJSObjectLiteral(CreateElement(TJSObjectLiteral,El));
|
Result:=nil;
|
||||||
For I:=0 to Length(El.Fields)-1 do
|
aResolver:=AContext.Resolver;
|
||||||
begin
|
ok:=false;
|
||||||
RVI:=El.Fields[i];
|
try
|
||||||
Rel:=R.Elements.AddElement;
|
if aResolver<>nil then
|
||||||
Rel.Name:=TJSString(RVI.Name);
|
begin
|
||||||
Rel.Expr:=ConvertElement(RVI.ValueExp,AContext);
|
// with resolver: new TRecord({...})
|
||||||
end;
|
aResolver.ComputeElement(El,ResolvedEl,[]);
|
||||||
Result:=R;
|
if (ResolvedEl.BaseType<>btContext)
|
||||||
|
or (ResolvedEl.LoTypeEl.ClassType<>TPasRecordType) then
|
||||||
|
RaiseNotSupported(El,AContext,20180429210932);
|
||||||
|
RecType:=TPasRecordType(ResolvedEl.LoTypeEl);
|
||||||
|
|
||||||
|
NewMemE:=TJSNewMemberExpression(CreateElement(TJSNewMemberExpression,El));
|
||||||
|
Result:=NewMemE;
|
||||||
|
NewMemE.MExpr:=CreateReferencePathExpr(RecType,AContext);
|
||||||
|
ObjLit:=TJSObjectLiteral(CreateElement(TJSObjectLiteral,El));
|
||||||
|
NewMemE.AddArg(ObjLit);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
// without resolver: {...}
|
||||||
|
ObjLit:=TJSObjectLiteral(CreateElement(TJSObjectLiteral,El));
|
||||||
|
Result:=ObjLit;;
|
||||||
|
end;
|
||||||
|
RecFields:=El.Fields;
|
||||||
|
for i:=0 to length(RecFields)-1 do
|
||||||
|
begin
|
||||||
|
Field:=@RecFields[i];
|
||||||
|
Ref:=Field^.NameExp.CustomData as TResolvedReference;
|
||||||
|
Member:=Ref.Declaration as TPasVariable;
|
||||||
|
ObjLitEl:=ObjLit.Elements.AddElement;
|
||||||
|
ObjLitEl.Name:=TJSString(TransformVariableName(Member,AContext));
|
||||||
|
ObjLitEl.Expr:=CreateValInit(Member.VarType,Field^.ValueExp,Field^.NameExp,AContext);
|
||||||
|
end;
|
||||||
|
ok:=true;
|
||||||
|
finally
|
||||||
|
if not ok then
|
||||||
|
Result.Free;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TPasToJSConverter.ConvertArrayValues(El: TArrayValues;
|
function TPasToJSConverter.ConvertArrayValues(El: TArrayValues;
|
||||||
@ -16132,31 +16170,38 @@ var
|
|||||||
NewMemE: TJSNewMemberExpression;
|
NewMemE: TJSNewMemberExpression;
|
||||||
aResolver: TPas2JSResolver;
|
aResolver: TPas2JSResolver;
|
||||||
ObjLit: TJSObjectLiteral;
|
ObjLit: TJSObjectLiteral;
|
||||||
GUID: TGUID;
|
GUID: TGuid;
|
||||||
begin
|
begin
|
||||||
Result:=nil;
|
Result:=nil;
|
||||||
NewMemE:=TJSNewMemberExpression(CreateElement(TJSNewMemberExpression,El));
|
if Expr<>nil then
|
||||||
try
|
begin
|
||||||
NewMemE.MExpr:=CreateReferencePathExpr(aRecord,AContext);
|
aResolver:=AContext.Resolver;
|
||||||
if Expr<>nil then
|
if aResolver<>nil then
|
||||||
begin
|
begin
|
||||||
aResolver:=AContext.Resolver;
|
if aResolver.GetAssignGUIDString(aRecord,Expr,GUID) then
|
||||||
if aResolver<>nil then
|
|
||||||
begin
|
begin
|
||||||
if aResolver.GetAssignGUIDString(aRecord,Expr,GUID) then
|
// new TGuid({ D1:...})
|
||||||
begin
|
ObjLit:=CreateGUIDObjLit(aRecord,GUID,El,AContext);
|
||||||
ObjLit:=CreateGUIDObjLit(aRecord,GUID,El,AContext);
|
NewMemE:=TJSNewMemberExpression(CreateElement(TJSNewMemberExpression,El));
|
||||||
NewMemE.AddArg(ObjLit);
|
Result:=NewMemE;
|
||||||
end;
|
NewMemE.MExpr:=CreateReferencePathExpr(aRecord,AContext);
|
||||||
|
NewMemE.AddArg(ObjLit);
|
||||||
|
exit;
|
||||||
end;
|
end;
|
||||||
if NewMemE.Args=nil then
|
|
||||||
RaiseNotSupported(Expr,AContext,20161024192747);
|
|
||||||
end;
|
end;
|
||||||
Result:=NewMemE;
|
if Expr is TRecordValues then
|
||||||
finally
|
// new TRecord({...})
|
||||||
|
Result:=ConvertRecordValues(TRecordValues(Expr),AContext);
|
||||||
if Result=nil then
|
if Result=nil then
|
||||||
NewMemE.Free;
|
RaiseNotSupported(Expr,AContext,20161024192747);
|
||||||
end;
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
// new TRecord()
|
||||||
|
NewMemE:=TJSNewMemberExpression(CreateElement(TJSNewMemberExpression,El));
|
||||||
|
Result:=NewMemE;
|
||||||
|
NewMemE.MExpr:=CreateReferencePathExpr(aRecord,AContext);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TPasToJSConverter.CreateReferencePath(El: TPasElement;
|
function TPasToJSConverter.CreateReferencePath(El: TPasElement;
|
||||||
|
@ -370,7 +370,7 @@ type
|
|||||||
Procedure TestRecord_TypeCastJSValueToRecord;
|
Procedure TestRecord_TypeCastJSValueToRecord;
|
||||||
Procedure TestRecord_VariantFail;
|
Procedure TestRecord_VariantFail;
|
||||||
Procedure TestRecord_FieldArray;
|
Procedure TestRecord_FieldArray;
|
||||||
// ToDo: const record
|
Procedure TestRecord_Const;
|
||||||
|
|
||||||
// classes
|
// classes
|
||||||
Procedure TestClass_TObjectDefaultConstructor;
|
Procedure TestClass_TObjectDefaultConstructor;
|
||||||
@ -624,7 +624,6 @@ type
|
|||||||
Procedure TestResourcestringProgram;
|
Procedure TestResourcestringProgram;
|
||||||
Procedure TestResourcestringUnit;
|
Procedure TestResourcestringUnit;
|
||||||
Procedure TestResourcestringImplementation;
|
Procedure TestResourcestringImplementation;
|
||||||
// ToDo: in unit interface and implementation
|
|
||||||
|
|
||||||
// Attributes
|
// Attributes
|
||||||
Procedure TestAtributes_Ignore;
|
Procedure TestAtributes_Ignore;
|
||||||
@ -7980,6 +7979,86 @@ begin
|
|||||||
'']));
|
'']));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestModule.TestRecord_Const;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'type',
|
||||||
|
' TArrInt = array[3..4] of longint;',
|
||||||
|
' TPoint = record x,y: longint; end;',
|
||||||
|
' TRec = record',
|
||||||
|
' i: longint;',
|
||||||
|
' a: array of longint;',
|
||||||
|
' s: array[1..2] of longint;',
|
||||||
|
' m: array[1..2,3..4] of longint;',
|
||||||
|
' p: TPoint;',
|
||||||
|
' end;',
|
||||||
|
' TPoints = array of TPoint;',
|
||||||
|
'const',
|
||||||
|
' r: TRec = (',
|
||||||
|
' i:1;',
|
||||||
|
' a:(2,3);',
|
||||||
|
' s:(4,5);',
|
||||||
|
' m:( (11,12), (13,14) );',
|
||||||
|
' p: (x:21; y:22)',
|
||||||
|
' );',
|
||||||
|
' p: TPoints = ( (x:1;y:2), (x:3;y:4) );',
|
||||||
|
'begin']);
|
||||||
|
ConvertProgram;
|
||||||
|
CheckSource('TestRecord_Const',
|
||||||
|
LinesToStr([ // statements
|
||||||
|
'this.TPoint = function (s) {',
|
||||||
|
' if (s) {',
|
||||||
|
' this.x = s.x;',
|
||||||
|
' this.y = s.y;',
|
||||||
|
' } else {',
|
||||||
|
' this.x = 0;',
|
||||||
|
' this.y = 0;',
|
||||||
|
' };',
|
||||||
|
' this.$equal = function (b) {',
|
||||||
|
' return (this.x === b.x) && (this.y === b.y);',
|
||||||
|
' };',
|
||||||
|
'};',
|
||||||
|
'this.TRec = function (s) {',
|
||||||
|
' if (s) {',
|
||||||
|
' this.i = s.i;',
|
||||||
|
' this.a = s.a;',
|
||||||
|
' this.s = s.s.slice(0);',
|
||||||
|
' this.m = s.m.slice(0);',
|
||||||
|
' this.p = new $mod.TPoint(s.p);',
|
||||||
|
' } else {',
|
||||||
|
' this.i = 0;',
|
||||||
|
' this.a = [];',
|
||||||
|
' this.s = rtl.arraySetLength(null, 0, 2);',
|
||||||
|
' this.m = rtl.arraySetLength(null, 0, 2, 2);',
|
||||||
|
' this.p = new $mod.TPoint();',
|
||||||
|
' };',
|
||||||
|
' this.$equal = function (b) {',
|
||||||
|
' return (this.i === b.i) && ((this.a === b.a) && (rtl.arrayEq(this.s, b.s) && (rtl.arrayEq(this.m, b.m) && this.p.$equal(b.p))));',
|
||||||
|
' };',
|
||||||
|
'};',
|
||||||
|
'this.r = new $mod.TRec({',
|
||||||
|
' i: 1,',
|
||||||
|
' a: [2, 3],',
|
||||||
|
' s: [4, 5],',
|
||||||
|
' m: [[11, 12], [13, 14]],',
|
||||||
|
' p: new $mod.TPoint({',
|
||||||
|
' x: 21,',
|
||||||
|
' y: 22',
|
||||||
|
' })',
|
||||||
|
'});',
|
||||||
|
'this.p = [new $mod.TPoint({',
|
||||||
|
' x: 1,',
|
||||||
|
' y: 2',
|
||||||
|
'}), new $mod.TPoint({',
|
||||||
|
' x: 3,',
|
||||||
|
' y: 4',
|
||||||
|
'})];',
|
||||||
|
'']),
|
||||||
|
LinesToStr([ // $mod.$main
|
||||||
|
'']));
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestModule.TestClass_TObjectDefaultConstructor;
|
procedure TTestModule.TestClass_TObjectDefaultConstructor;
|
||||||
begin
|
begin
|
||||||
StartProgram(false);
|
StartProgram(false);
|
||||||
|
Loading…
Reference in New Issue
Block a user