mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 08:48:08 +02:00
pastojs: generate elevated local types as vars
git-svn-id: trunk@40722 -
This commit is contained in:
parent
a2cee252e8
commit
9d079bfb97
@ -12625,6 +12625,7 @@ var
|
||||
OrdType: TOrdType;
|
||||
Src: TJSSourceElements;
|
||||
ProcScope: TPas2JSProcedureScope;
|
||||
VarSt: TJSVariableStatement;
|
||||
begin
|
||||
Result:=nil;
|
||||
for i:=0 to El.Values.Count-1 do
|
||||
@ -12637,6 +12638,9 @@ begin
|
||||
ok:=false;
|
||||
ObjectContect:=nil;
|
||||
Src:=nil;
|
||||
Call:=nil;
|
||||
VarSt:=nil;
|
||||
ProcScope:=nil;
|
||||
try
|
||||
Obj:=TJSObjectLiteral(CreateElement(TJSObjectLiteral,El));
|
||||
if AContext is TObjectContext then
|
||||
@ -12651,21 +12655,22 @@ begin
|
||||
else if El.Parent is TProcedureBody then
|
||||
begin
|
||||
// add 'var TypeName = {}'
|
||||
if (AContext<>nil) and (AContext.JSElement is TJSSourceElements) then
|
||||
Src:=TJSSourceElements(AContext.JSElement)
|
||||
VarSt:=CreateVarStatement(TransformVariableName(El,AContext),Obj,El);
|
||||
if AContext.JSElement is TJSSourceElements then
|
||||
begin
|
||||
Src:=TJSSourceElements(AContext.JSElement);
|
||||
AddToSourceElements(Src,VarSt); // keep Result=nil
|
||||
end
|
||||
else
|
||||
Result:=CreateVarStatement(TransformVariableName(El,AContext),Obj,El);
|
||||
end;
|
||||
if Result=nil then
|
||||
Result:=VarSt;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// add 'this.TypeName = {}'
|
||||
AssignSt:=TJSSimpleAssignStatement(CreateElement(TJSSimpleAssignStatement,El));
|
||||
AssignSt.LHS:=CreateSubDeclNameExpr(El,AContext);
|
||||
AssignSt.Expr:=Obj;
|
||||
if Src<>nil then
|
||||
AddToSourceElements(Src,AssignSt) // keep Result=nil
|
||||
else
|
||||
Result:=AssignSt;
|
||||
Result:=AssignSt;
|
||||
end;
|
||||
|
||||
ObjectContect:=TObjectContext.Create(El,Obj,AContext);
|
||||
@ -12683,21 +12688,22 @@ begin
|
||||
ObjLit.Expr:=CreateLiteralNumber(El,i);
|
||||
end;
|
||||
|
||||
if Src<>nil then
|
||||
begin
|
||||
// store precompiled enum type in proc
|
||||
ProcScope:=GetImplJSProcScope(El,Src,AContext);
|
||||
if ProcScope<>nil then
|
||||
ProcScope.AddGlobalJS(CreatePrecompiledJS(VarSt));
|
||||
end;
|
||||
|
||||
if HasTypeInfo(El,AContext) then
|
||||
begin
|
||||
// create typeinfo
|
||||
if not (AContext is TFunctionContext) then
|
||||
RaiseNotSupported(El,AContext,20170411210045,'typeinfo');
|
||||
if Src<>nil then
|
||||
RaiseNotSupported(El,AContext,20181231005005);
|
||||
// create statement list
|
||||
List:=TJSStatementList(CreateElement(TJSStatementList,El));
|
||||
List.A:=Result;
|
||||
Result:=List;
|
||||
OrdType:=GetOrdType(0,TMaxPrecInt(El.Values.Count)-1,El);
|
||||
// module.$rtti.$TIEnum("TMyEnum",{...});
|
||||
Call:=CreateRTTINewType(El,GetBIName(pbifnRTTINewEnum),false,AContext,TIObj);
|
||||
List.B:=Call;
|
||||
// add minvalue: number
|
||||
TIProp:=TIObj.Elements.AddElement;
|
||||
TIProp.Name:=TJSString(GetBIName(pbivnRTTIInt_MinValue));
|
||||
@ -12714,15 +12720,30 @@ begin
|
||||
TIProp:=TIObj.Elements.AddElement;
|
||||
TIProp.Name:=TJSString(GetBIName(pbivnRTTIEnum_EnumType));
|
||||
TIProp.Expr:=CreateSubDeclNameExpr(El,AContext);
|
||||
end;
|
||||
|
||||
// store precompiled enum type in proc
|
||||
ProcScope:=GetImplJSProcScope(El,Src,AContext);
|
||||
if ProcScope<>nil then
|
||||
ProcScope.AddGlobalJS(CreatePrecompiledJS(AssignSt));
|
||||
if Src<>nil then
|
||||
begin
|
||||
// add to source elements
|
||||
AddToSourceElements(Src,Call);
|
||||
if ProcScope<>nil then
|
||||
ProcScope.AddGlobalJS(CreatePrecompiledJS(Call));
|
||||
end
|
||||
else if Result=nil then
|
||||
RaiseNotSupported(El,AContext,20190101130432)
|
||||
else
|
||||
begin
|
||||
// create statement list
|
||||
List:=TJSStatementList(CreateElement(TJSStatementList,El));
|
||||
List.A:=Result;
|
||||
Result:=List;
|
||||
List.B:=Call;
|
||||
end;
|
||||
Call:=nil;
|
||||
end;
|
||||
|
||||
ok:=true;
|
||||
finally
|
||||
Call.Free;
|
||||
ObjectContect.Free;
|
||||
if not ok then
|
||||
FreeAndNil(Result);
|
||||
@ -12996,9 +13017,22 @@ const
|
||||
CloneArrName = 'a';
|
||||
CloneResultName = 'r';
|
||||
CloneRunName = 'i';
|
||||
var
|
||||
ProcScope: TPas2JSProcedureScope;
|
||||
Src: TJSSourceElements;
|
||||
|
||||
procedure StorePrecompiledJS(JS: TJSElement);
|
||||
begin
|
||||
// store precompiled enum type in proc
|
||||
if ProcScope=nil then
|
||||
ProcScope:=GetImplJSProcScope(El,Src,AContext);
|
||||
if ProcScope<>nil then
|
||||
ProcScope.AddGlobalJS(CreatePrecompiledJS(JS));
|
||||
end;
|
||||
|
||||
var
|
||||
AssignSt: TJSSimpleAssignStatement;
|
||||
CallName: String;
|
||||
CallName, ArrName: String;
|
||||
Obj: TJSObjectLiteral;
|
||||
Prop: TJSObjectLiteralElement;
|
||||
ArrLit: TJSArrayLiteral;
|
||||
@ -13010,15 +13044,14 @@ var
|
||||
RgLen, RangeEnd: TMaxPrecInt;
|
||||
List: TJSStatementList;
|
||||
Func: TJSFunctionDeclarationStatement;
|
||||
BodySrc, Src: TJSSourceElements;
|
||||
BodySrc: TJSSourceElements;
|
||||
VarSt: TJSVariableStatement;
|
||||
ForLoop: TJSForStatement;
|
||||
ExprLT: TJSRelationalExpressionLT;
|
||||
PlusPlus: TJSUnaryPostPlusPlusExpression;
|
||||
BracketEx: TJSBracketMemberExpression;
|
||||
CloneEl: TJSElement;
|
||||
ArraySt, CloneEl: TJSElement;
|
||||
ReturnSt: TJSReturnStatement;
|
||||
ProcScope: TPas2JSProcedureScope;
|
||||
begin
|
||||
Result:=nil;
|
||||
if El.PackMode<>pmNone then
|
||||
@ -13028,8 +13061,9 @@ begin
|
||||
writeln('TPasToJSConverter.ConvertArrayType ',GetObjName(El));
|
||||
{$ENDIF}
|
||||
|
||||
ProcScope:=nil;
|
||||
Src:=nil;
|
||||
if (AContext<>nil) and (AContext.JSElement is TJSSourceElements) then
|
||||
if AContext.JSElement is TJSSourceElements then
|
||||
Src:=TJSSourceElements(AContext.JSElement);
|
||||
|
||||
if AContext.Resolver.HasStaticArrayCloneFunc(El) then
|
||||
@ -13041,17 +13075,13 @@ begin
|
||||
// return r;
|
||||
// };
|
||||
BracketEx:=nil;
|
||||
AssignSt:=TJSSimpleAssignStatement(CreateElement(TJSSimpleAssignStatement,El));
|
||||
AssignSt:=nil;
|
||||
Func:=nil;
|
||||
try
|
||||
// add 'this.TypeName = function(){}'
|
||||
AssignSt.LHS:=CreateSubDeclNameExpr(El,
|
||||
El.Name+GetBIName(pbifnArray_Static_Clone),AContext);
|
||||
|
||||
Index:=0;
|
||||
RangeEl:=El.Ranges[Index];
|
||||
// function(a){...
|
||||
Func:=CreateFunctionSt(El,true,true);
|
||||
AssignSt.Expr:=Func;
|
||||
Func.AFunction.Params.Add(CloneArrName);
|
||||
BodySrc:=Func.AFunction.Body.A as TJSSourceElements;
|
||||
// var r = [];
|
||||
@ -13102,29 +13132,43 @@ begin
|
||||
AddToSourceElements(BodySrc,ReturnSt);
|
||||
ReturnSt.Expr:=CreatePrimitiveDotExpr(CloneResultName,El);
|
||||
|
||||
if Src<>nil then
|
||||
AddToSourceElements(Src,AssignSt)
|
||||
ArrName:=El.Name+GetBIName(pbifnArray_Static_Clone);
|
||||
if El.Parent is TProcedureBody then
|
||||
begin
|
||||
// local array type (elevated to global)
|
||||
// -> add 'var TypeName = function(){}'
|
||||
ArraySt:=CreateVarStatement(ArrName,Func,El);
|
||||
end
|
||||
else
|
||||
Result:=AssignSt;
|
||||
begin
|
||||
// global array type
|
||||
// -> add 'this.TypeName = function(){}'
|
||||
AssignSt:=TJSSimpleAssignStatement(CreateElement(TJSSimpleAssignStatement,El));
|
||||
ArraySt:=AssignSt;
|
||||
AssignSt.LHS:=CreateSubDeclNameExpr(El,ArrName,AContext);
|
||||
AssignSt.Expr:=Func;
|
||||
end;
|
||||
Func:=nil;
|
||||
|
||||
if Src<>nil then
|
||||
AddToSourceElements(Src,ArraySt)
|
||||
else
|
||||
Result:=ArraySt;
|
||||
|
||||
// store precompiled enum type in proc
|
||||
ProcScope:=GetImplJSProcScope(El,Src,AContext);
|
||||
if ProcScope<>nil then
|
||||
ProcScope.AddGlobalJS(CreatePrecompiledJS(AssignSt));
|
||||
StorePrecompiledJS(ArraySt);
|
||||
|
||||
AssignSt:=nil;
|
||||
ArraySt:=nil;
|
||||
finally
|
||||
BracketEx.Free;
|
||||
AssignSt.Free;
|
||||
Func.Free;
|
||||
ArraySt.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
if HasTypeInfo(El,AContext) then
|
||||
begin
|
||||
|
||||
if El.Parent is TProcedureBody then
|
||||
RaiseNotSupported(El,AContext,20181231113427);
|
||||
|
||||
// module.$rtti.$DynArray("name",{...})
|
||||
if length(El.Ranges)>0 then
|
||||
CallName:=GetBIName(pbifnRTTINewStaticArray)
|
||||
@ -13164,7 +13208,14 @@ begin
|
||||
Prop:=Obj.Elements.AddElement;
|
||||
Prop.Name:=TJSString(GetBIName(pbivnRTTIArray_ElType));
|
||||
Prop.Expr:=CreateTypeInfoRef(ElType,AContext,El);
|
||||
if Result=nil then
|
||||
|
||||
if Src<>nil then
|
||||
begin
|
||||
AddToSourceElements(Src,Call);
|
||||
// store precompiled rtti call in proc
|
||||
StorePrecompiledJS(Call);
|
||||
end
|
||||
else if Result=nil then
|
||||
Result:=Call
|
||||
else
|
||||
begin
|
||||
@ -19754,6 +19805,7 @@ var
|
||||
BodyFirst, BodyLast, ListFirst: TJSStatementList;
|
||||
FuncContext: TFunctionContext;
|
||||
ObjLit: TJSObjectLiteral;
|
||||
VarSt: TJSVariableStatement;
|
||||
IfSt: TJSIfStatement;
|
||||
Call, Call2: TJSCallExpression;
|
||||
ok: Boolean;
|
||||
@ -19765,23 +19817,33 @@ begin
|
||||
Result:=nil;
|
||||
FuncContext:=nil;
|
||||
ListFirst:=nil;
|
||||
VarSt:=nil;
|
||||
Src:=nil;
|
||||
ProcScope:=nil;
|
||||
ok:=false;
|
||||
try
|
||||
FDS:=CreateFunctionSt(El);
|
||||
FD:=FDS.AFunction;
|
||||
// types are stored in interface/implementation
|
||||
if (El.Parent is TProcedureBody)
|
||||
and (AContext.JSElement is TJSSourceElements) then
|
||||
Src:=TJSSourceElements(AContext.JSElement);
|
||||
// add 'this.TypeName = function(){}'
|
||||
AssignSt:=TJSSimpleAssignStatement(CreateElement(TJSSimpleAssignStatement,El));
|
||||
AssignSt.LHS:=CreateSubDeclNameExpr(El,AContext);
|
||||
AssignSt.Expr:=FDS;
|
||||
if Src<>nil then
|
||||
AddToSourceElements(Src,AssignSt) // keep Result=nil
|
||||
if El.Parent is TProcedureBody then
|
||||
begin
|
||||
// add 'var TypeName = function(){}'
|
||||
if AContext.JSElement is TJSSourceElements then
|
||||
Src:=TJSSourceElements(AContext.JSElement);
|
||||
VarSt:=CreateVarStatement(TransformVariableName(El,AContext),FDS,El);
|
||||
if Src<>nil then
|
||||
AddToSourceElements(Src,VarSt) // keep Result=nil
|
||||
else
|
||||
Result:=VarSt;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// add 'this.TypeName = function(){}'
|
||||
AssignSt:=TJSSimpleAssignStatement(CreateElement(TJSSimpleAssignStatement,El));
|
||||
AssignSt.LHS:=CreateSubDeclNameExpr(El,AContext);
|
||||
AssignSt.Expr:=FDS;
|
||||
Result:=AssignSt;
|
||||
end;
|
||||
|
||||
// add param s
|
||||
FD.Params.Add(SrcParamName);
|
||||
@ -19808,13 +19870,19 @@ begin
|
||||
if FD.Body.A=nil then
|
||||
FD.Body.A:=BodyFirst;
|
||||
|
||||
if Src<>nil then
|
||||
begin
|
||||
// store precompiled record type in proc
|
||||
ProcScope:=GetImplJSProcScope(El,Src,AContext);
|
||||
if ProcScope<>nil then
|
||||
ProcScope.AddGlobalJS(CreatePrecompiledJS(VarSt));
|
||||
end;
|
||||
|
||||
if HasTypeInfo(El,AContext) then
|
||||
begin
|
||||
// add $rtti as second statement
|
||||
if not (AContext is TFunctionContext) then
|
||||
RaiseNotSupported(El,AContext,20170412120012);
|
||||
if Src<>nil then
|
||||
RaiseNotSupported(El,AContext,20181231005023);
|
||||
|
||||
// module.$rtti.$Record("typename",{});
|
||||
Call:=CreateRTTINewType(El,GetBIName(pbifnRTTINewRecord),false,AContext,ObjLit);
|
||||
@ -19831,9 +19899,16 @@ begin
|
||||
Call:=Call2;
|
||||
AddRTTIFields(Call.Args);
|
||||
end;
|
||||
|
||||
if Src<>nil then
|
||||
begin
|
||||
// add Call to global statements
|
||||
AddToSourceElements(Src,Call)
|
||||
AddToSourceElements(Src,Call);
|
||||
if ProcScope<>nil then
|
||||
ProcScope.AddGlobalJS(CreatePrecompiledJS(VarSt));
|
||||
end
|
||||
else if Result=nil then
|
||||
RaiseNotSupported(El,AContext,20190101130409)
|
||||
else
|
||||
begin
|
||||
// combine Result and Call into a statement list
|
||||
@ -19846,10 +19921,6 @@ begin
|
||||
|
||||
end;
|
||||
|
||||
// store precompiled record type in proc
|
||||
ProcScope:=GetImplJSProcScope(El,Src,AContext);
|
||||
if ProcScope<>nil then
|
||||
ProcScope.AddGlobalJS(CreatePrecompiledJS(Result));
|
||||
ok:=true;
|
||||
finally
|
||||
FuncContext.Free;
|
||||
|
@ -456,6 +456,7 @@ type
|
||||
// ToDo: TestAdvRecord_PropertyDefault;
|
||||
// ToDo: TestAdvRecord_InFunction;
|
||||
// ToDo: pcu: record default property
|
||||
// ToDo: class constructor
|
||||
|
||||
// classes
|
||||
Procedure TestClass_TObjectDefaultConstructor;
|
||||
@ -4764,7 +4765,7 @@ begin
|
||||
CheckSource('TestEnum_InFunction',
|
||||
LinesToStr([ // statements
|
||||
'this.TEnum = 3;',
|
||||
'this.TEnum$1 = {',
|
||||
'var TEnum$1 = {',
|
||||
' "0":"Red",',
|
||||
' Red:0,',
|
||||
' "1":"Green",',
|
||||
@ -4772,7 +4773,7 @@ begin
|
||||
' "2":"Blue",',
|
||||
' Blue:2',
|
||||
' };',
|
||||
'this.TEnumSub = {',
|
||||
'var TEnumSub = {',
|
||||
' "0": "Left",',
|
||||
' Left: 0,',
|
||||
' "1": "Right",',
|
||||
@ -5487,13 +5488,13 @@ begin
|
||||
'this.TEnum = 3;',
|
||||
'this.TSetOfEnum = 4;',
|
||||
'this.TSetOfAno = 5;',
|
||||
'this.TEnum$1 = {',
|
||||
'var TEnum$1 = {',
|
||||
' "0": "red",',
|
||||
' red: 0,',
|
||||
' "1": "blue",',
|
||||
' blue: 1',
|
||||
'};',
|
||||
'this.TSetOfAno$a = {',
|
||||
'var TSetOfAno$a = {',
|
||||
' "0": "up",',
|
||||
' up: 0,',
|
||||
' "1": "down",',
|
||||
@ -7953,7 +7954,7 @@ begin
|
||||
LinesToStr([ // statements
|
||||
'this.TArrayInt = 3;',
|
||||
'this.TArrayArrayInt = 4;',
|
||||
'this.TArrayArrayInt$1$clone = function (a) {',
|
||||
'var TArrayArrayInt$1$clone = function (a) {',
|
||||
' var r = [];',
|
||||
' for (var i = 0; i < 2; i++) r.push(a[i].slice(0));',
|
||||
' return r;',
|
||||
@ -9886,7 +9887,7 @@ begin
|
||||
CheckSource('TestRecord_InFunction',
|
||||
LinesToStr([ // statements
|
||||
'this.TPoint = 3;',
|
||||
'this.TPoint$1 = function (s) {',
|
||||
'var TPoint$1 = function (s) {',
|
||||
' if (s) {',
|
||||
' this.x = s.x;',
|
||||
' this.y = s.y;',
|
||||
@ -22004,13 +22005,14 @@ begin
|
||||
' TPoint = record',
|
||||
' x,y: integer;',
|
||||
' end;',
|
||||
'var p: TPoint;',
|
||||
'begin',
|
||||
'end;',
|
||||
'begin']);
|
||||
ConvertProgram;
|
||||
CheckSource('TestRTTI_LocalTypes',
|
||||
LinesToStr([ // statements
|
||||
'this.TPoint = function(s) {',
|
||||
'var TPoint = function(s) {',
|
||||
' if (s) {',
|
||||
' this.x = s.x;',
|
||||
' this.y = s.y;',
|
||||
@ -22023,6 +22025,7 @@ begin
|
||||
' };',
|
||||
'};',
|
||||
'this.DoIt = function () {',
|
||||
' var p = new TPoint();',
|
||||
'};',
|
||||
'']),
|
||||
LinesToStr([ // $mod.$main
|
||||
|
Loading…
Reference in New Issue
Block a user