pastojs: srcmap: keep position at curly brackets, fixed bracket accessor

git-svn-id: trunk@37264 -
This commit is contained in:
Mattias Gaertner 2017-09-20 09:13:01 +00:00
parent 4b4e40c98e
commit 77b1cfcd0d
4 changed files with 131 additions and 154 deletions

View File

@ -51,7 +51,7 @@ Works:
ToDo:
- arrays
- [], [a..b], [a,b], +
- [], [a..b], multi dim [a,b], concat with +
- array of record
- array of string
- error on: array[1..2] of longint = (1,2,3);

View File

@ -1132,7 +1132,7 @@ type
FPreservedWords: TJSReservedWordList; // sorted with CompareStr
FTargetPlatform: TPasToJsPlatform;
FTargetProcessor: TPasToJsProcessor;
Function CreatePrimitiveDotExpr(AName: string; Src: TPasElement = nil): TJSElement;
Function CreatePrimitiveDotExpr(AName: string; Src: TPasElement): TJSElement;
Function CreateSubDeclNameExpr(El: TPasElement; const Name: string;
AContext: TConvertContext; PosEl: TPasElement = nil): TJSElement;
Function CreateIdentifierExpr(El: TPasElement; AContext: TConvertContext): TJSElement;
@ -3595,7 +3595,7 @@ begin
ModVarName:=FBuiltInNames[pbivnModule];
IntfContext.AddLocalVar(ModVarName,El);
AddToSourceElements(Src,CreateVarStatement(ModVarName,
CreatePrimitiveDotExpr('this'),El));
CreatePrimitiveDotExpr('this',El),El));
if (El is TPasProgram) then
begin // program
@ -3710,7 +3710,7 @@ begin
else
FunName:=FBuiltInNames[pbifnClassInstanceFree];
FunName:=CreateReferencePath(Proc,AContext,rpkPathWithDot,false,Ref)+FunName;
C.Expr:=CreatePrimitiveDotExpr(FunName);
C.Expr:=CreatePrimitiveDotExpr(FunName,Ref.Element);
ArgElems:=C.Args.Elements;
// parameter: "funcname"
ArgEx := CreateLiteralString(Ref.Element,TransformVariableName(Proc,AContext));
@ -4099,12 +4099,13 @@ begin
begin
// "A as B"
Call:=CreateCallExpression(El);
if (RightResolved.TypeEl is TPasClassType) and TPasClassType(RightResolved.TypeEl).IsExternal then
if (RightResolved.TypeEl is TPasClassType)
and TPasClassType(RightResolved.TypeEl).IsExternal then
// B is external class -> "rtl.asExt(A,B)"
Call.Expr:=CreatePrimitiveDotExpr(FBuiltInNames[pbivnRTL]+'.'+FBuiltInNames[pbifnAsExt])
Call.Expr:=CreatePrimitiveDotExpr(FBuiltInNames[pbivnRTL]+'.'+FBuiltInNames[pbifnAsExt],El)
else
// otherwise -> "rtl.as(A,B)"
Call.Expr:=CreatePrimitiveDotExpr(FBuiltInNames[pbivnRTL]+'.'+FBuiltInNames[pbifnAs]);
Call.Expr:=CreatePrimitiveDotExpr(FBuiltInNames[pbivnRTL]+'.'+FBuiltInNames[pbifnAs],El);
Call.AddArg(A);
Call.AddArg(B);
Result:=Call;
@ -4137,7 +4138,7 @@ begin
eopPower:
begin
Call:=CreateCallExpression(El);
Call.Expr:=CreatePrimitiveDotExpr('Math.pow');
Call.Expr:=CreatePrimitiveDotExpr('Math.pow',El);
Call.AddArg(A);
Call.AddArg(B);
Result:=Call;
@ -4158,7 +4159,7 @@ begin
// convert "a div b" to "Math.floor(a/b)"
Call:=CreateCallExpression(El);
Call.AddArg(R);
Call.Expr:=CreatePrimitiveDotExpr('Math.floor');
Call.Expr:=CreatePrimitiveDotExpr('Math.floor',El);
Result:=Call;
end;
end;
@ -4302,7 +4303,7 @@ begin
begin
// convert "recordA = recordB" to "recordA.$equal(recordB)"
Call:=CreateCallExpression(El);
Call.Expr:=CreateDotExpression(El,A,CreatePrimitiveDotExpr(FBuiltInNames[pbifnRecordEqual]));
Call.Expr:=CreateDotExpression(El,A,CreatePrimitiveDotExpr(FBuiltInNames[pbifnRecordEqual],El));
A:=nil;
Call.AddArg(B);
B:=nil;
@ -4658,7 +4659,7 @@ begin
Call:=CreateCallExpression(El);
Call.Expr:=CreateDotExpression(El,
CreateIdentifierExpr(Arg.Name,Arg,AContext),
CreatePrimitiveDotExpr(TempRefObjGetterName));
CreatePrimitiveDotExpr(TempRefObjGetterName,El));
Result:=Call;
exit;
end;
@ -4672,7 +4673,7 @@ begin
AssignContext.Call:=Call;
Call.Expr:=CreateDotExpression(El,
CreateIdentifierExpr(Arg.Name,Arg,AContext),
CreatePrimitiveDotExpr(TempRefObjSetterName));
CreatePrimitiveDotExpr(TempRefObjSetterName,El));
Call.AddArg(AssignContext.RightSide);
AssignContext.RightSide:=nil;
Result:=Call;
@ -4836,11 +4837,11 @@ function TPasToJSConverter.ConvertInheritedExpression(El: TInheritedExpr;
Call:=nil;
try
Call:=CreateCallExpression(ParentEl);
Call.Expr:=CreatePrimitiveDotExpr(FunName);
Call.AddArg(CreatePrimitiveDotExpr(SelfName));
Call.Expr:=CreatePrimitiveDotExpr(FunName,ParentEl);
Call.AddArg(CreatePrimitiveDotExpr(SelfName,ParentEl));
if Apply then
// "inherited;" -> pass the arguments
Call.AddArg(CreatePrimitiveDotExpr('arguments'))
Call.AddArg(CreatePrimitiveDotExpr('arguments',ParentEl))
else
// "inherited Name(...)" -> pass the user arguments
CreateProcedureCall(Call,ParamsExpr,AncestorProc.ProcType,AContext);
@ -5166,7 +5167,8 @@ var
begin
// convert char to int -> Arg.charCodeAt(0)
Call:=CreateCallExpression(Param);
Call.Expr:=CreateDotExpression(Param,Arg,CreatePrimitiveDotExpr('charCodeAt'));
Call.Expr:=CreateDotExpression(Param,Arg,
CreatePrimitiveDotExpr('charCodeAt',Param));
Arg:=Call;
Call.Args.AddElement(CreateLiteralNumber(Param,0));
end;
@ -5280,7 +5282,7 @@ var
if Prop.Args.Count<>1 then
RaiseInconsistency(20170403003753);
// bracket accessor of external class -> create PathEl[param]
Bracket:=TJSBracketMemberExpression(CreateElement(TJSBracketMemberExpression,Prop));
Bracket:=TJSBracketMemberExpression(CreateElement(TJSBracketMemberExpression,El.Params[0]));
try
PathEl:=El.Value;
if ChompPropName then
@ -5293,7 +5295,7 @@ var
Ref:=TResolvedReference(PathEl.CustomData);
Path:=CreateReferencePath(Prop,AContext,rpkPath,false,Ref);
if Path<>'' then
Bracket.MExpr:=CreatePrimitiveDotExpr(Path);
Bracket.MExpr:=CreatePrimitiveDotExpr(Path,PathEl);
PathEl:=nil;
end
else if (PathEl is TBinaryExpr)
@ -5819,7 +5821,7 @@ begin
else
// use external class name
ExtName:=(Proc.Parent as TPasClassType).ExternalName;
ExtNameEl:=CreatePrimitiveDotExpr(ExtName);
ExtNameEl:=CreatePrimitiveDotExpr(ExtName,Ref.Element);
end;
if CompareText(Proc.Name,'new')=0 then
@ -6308,7 +6310,7 @@ begin
// default: Param.length
Arg:=ConvertElement(Param,AContext);
Result:=CreateDotExpression(El,Arg,CreatePrimitiveDotExpr('length'));
Result:=CreateDotExpression(El,Arg,CreatePrimitiveDotExpr('length',El));
end;
function TPasToJSConverter.ConvertBuiltIn_SetLength(El: TParamsExpr;
@ -6466,7 +6468,7 @@ begin
ProcEl:=ProcEl.Parent;
if ProcEl is TPasFunction then
// in a function, "return result;"
TJSReturnStatement(Result).Expr:=CreatePrimitiveDotExpr(ResolverResultVar)
TJSReturnStatement(Result).Expr:=CreatePrimitiveDotExpr(ResolverResultVar,El)
else
; // in a procedure, "return;" which means "return undefined;"
end;
@ -6522,7 +6524,7 @@ begin
// create "ref.set"
Call.Expr:=CreateDotExpression(El,
CreateIdentifierExpr(ExprResolved.IdentEl,AContext),
CreatePrimitiveDotExpr(TempRefObjSetterName));
CreatePrimitiveDotExpr(TempRefObjSetterName,El));
// create "+"
if IsInc then
AddJS:=TJSAdditiveExpressionPlus(CreateElement(TJSAdditiveExpressionPlus,El))
@ -6533,7 +6535,7 @@ begin
AddJS.A:=TJSCallExpression(CreateElement(TJSCallExpression,El));
TJSCallExpression(AddJS.A).Expr:=CreateDotExpression(El,
CreateIdentifierExpr(ExprResolved.IdentEl,AContext),
CreatePrimitiveDotExpr(TempRefObjGetterName));
CreatePrimitiveDotExpr(TempRefObjGetterName,El));
// add "b"
AddJS.B:=ValueJS;
ValueJS:=nil;
@ -6687,7 +6689,8 @@ begin
Call:=nil;
try
Call:=CreateCallExpression(El);
Call.Expr:=CreateDotExpression(El,SubParamJS,CreatePrimitiveDotExpr('charCodeAt'));
Call.Expr:=CreateDotExpression(El,SubParamJS,
CreatePrimitiveDotExpr('charCodeAt',El));
Minus:=TJSAdditiveExpressionMinus(CreateElement(TJSAdditiveExpressionMinus,Param));
Call.AddArg(Minus);
if length(SubParams.Params)<>1 then
@ -6707,7 +6710,7 @@ begin
Result:=ConvertElement(Param,AContext);
// Note: convert Param first, as it might raise an exception
Call:=CreateCallExpression(El);
Call.Expr:=CreateDotExpression(El,Result,CreatePrimitiveDotExpr('charCodeAt'));
Call.Expr:=CreateDotExpression(El,Result,CreatePrimitiveDotExpr('charCodeAt',El));
Result:=Call;
exit;
end
@ -7083,7 +7086,7 @@ begin
// precision -> rtl El.toFixed(precision);
NeedStrLit:=false;
Call:=CreateCallExpression(El);
Call.Expr:=CreateDotExpression(El,Add,CreatePrimitiveDotExpr('toFixed'));
Call.Expr:=CreateDotExpression(El,Add,CreatePrimitiveDotExpr('toFixed',El));
Call.AddArg(ConvertElement(El.format2,AContext));
Add:=Call;
Call:=nil;
@ -7189,7 +7192,7 @@ begin
if Call.Expr=nil then
// default: array1.concat(array2,...)
Call.Expr:=CreateDotExpression(El,ConvertElement(Param0,AContext),
CreatePrimitiveDotExpr('concat'));
CreatePrimitiveDotExpr('concat',El));
for i:=1 to length(El.Params)-1 do
Call.AddArg(ConvertElement(El.Params[i],AContext));
Result:=Call;
@ -7271,7 +7274,7 @@ begin
try
Call:=CreateCallExpression(El);
ArrEl:=ConvertElement(El.Params[1],AContext);
Call.Expr:=CreateDotExpression(El,ArrEl,CreatePrimitiveDotExpr('splice'));
Call.Expr:=CreateDotExpression(El,ArrEl,CreatePrimitiveDotExpr('splice',El));
Call.AddArg(ConvertElement(El.Params[2],AContext));
Call.AddArg(CreateLiteralNumber(El,1));
Call.AddArg(ConvertElement(El.Params[0],AContext));
@ -7295,7 +7298,7 @@ begin
try
Call:=CreateCallExpression(El);
ArrEl:=ConvertElement(El.Params[0],AContext);
Call.Expr:=CreateDotExpression(El,ArrEl,CreatePrimitiveDotExpr('splice'));
Call.Expr:=CreateDotExpression(El,ArrEl,CreatePrimitiveDotExpr('splice',El));
Call.AddArg(ConvertElement(El.Params[1],AContext));
Call.AddArg(ConvertElement(El.Params[2],AContext));
Result:=Call;
@ -7345,7 +7348,7 @@ begin
// typeinfo(classinstance) -> classinstance.$rtti
// typeinfo(classof) -> classof.$rtti
Result:=ConvertElement(Param,AContext);
Result:=CreateDotExpression(El,Result,CreatePrimitiveDotExpr(FBuiltInNames[pbivnRTTI]));
Result:=CreateDotExpression(El,Result,CreatePrimitiveDotExpr(FBuiltInNames[pbivnRTTI],Param));
end
else
Result:=CreateTypeInfoRef(TypeEl,AContext,Param);
@ -7438,7 +7441,7 @@ begin
else
DotExpr:=TJSDotMemberExpression.Create(0,0);
DotExpr.Name:=TJSString(copy(AName,p+1,length(AName))); // do not lowercase
DotExpr.MExpr:=CreatePrimitiveDotExpr(LeftStr(AName,p-1));
DotExpr.MExpr:=CreatePrimitiveDotExpr(LeftStr(AName,p-1),Src);
Result:=DotExpr;
end
else
@ -7652,8 +7655,8 @@ Var
var
RetSt: TJSReturnStatement;
begin
RetSt:=TJSReturnStatement(CreateElement(TJSReturnStatement,El));
RetSt.Expr:=CreatePrimitiveDotExpr(ResolverResultVar);
RetSt:=TJSReturnStatement(CreateElement(TJSReturnStatement,ResultEl));
RetSt.Expr:=CreatePrimitiveDotExpr(ResolverResultVar,ResultEl);
Add(RetSt,ResultEl);
end;
@ -7773,8 +7776,8 @@ var
exit;
Call:=CreateCallExpression(El);
AncestorPath:=CreateReferencePath(Ancestor,ClassContext,rpkPathAndName);
Call.Expr:=CreatePrimitiveDotExpr(AncestorPath+'.'+MemberFuncName[Kind]+'.call');
Call.AddArg(CreatePrimitiveDotExpr('this'));
Call.Expr:=CreatePrimitiveDotExpr(AncestorPath+'.'+MemberFuncName[Kind]+'.call',El);
Call.AddArg(CreatePrimitiveDotExpr('this',El));
AddToSourceElements(Src,Call);
end;
@ -7964,7 +7967,7 @@ begin
OwnerName:=AContext.GetLocalName(El.GetModule);
if OwnerName='' then
OwnerName:='this';
Call.AddArg(CreatePrimitiveDotExpr(OwnerName));
Call.AddArg(CreatePrimitiveDotExpr(OwnerName,El));
// add parameter: string constant '"classname"'
ArgEx := CreateLiteralString(El,TransformVariableName(El,AContext));
@ -7977,7 +7980,7 @@ begin
AncestorPath:=TPasClassType(Ancestor).ExternalName
else
AncestorPath:=CreateReferencePath(Ancestor,AContext,rpkPathAndName);
Call.AddArg(CreatePrimitiveDotExpr(AncestorPath));
Call.AddArg(CreatePrimitiveDotExpr(AncestorPath,El));
if AncestorIsExternal then
begin
@ -8658,7 +8661,7 @@ begin
// has nested procs -> add "var self = this;"
FuncContext.AddLocalVar(FBuiltInNames[pbivnSelf],FuncContext.ThisPas);
SelfSt:=CreateVarStatement(FBuiltInNames[pbivnSelf],
CreatePrimitiveDotExpr('this'),ImplProc);
CreatePrimitiveDotExpr('this',ImplProc),ImplProc);
AddBodyStatement(SelfSt,BodyPas);
if ImplProcScope.SelfArg<>nil then
begin
@ -8705,13 +8708,11 @@ end;
function TPasToJSConverter.ConvertImplBlockElements(El: TPasImplBlock;
AContext: TConvertContext; NilIfEmpty: boolean): TJSElement;
var
First, Last: TJSStatementList;
I : Integer;
PasImpl: TPasImplElement;
JSImpl : TJSElement;
begin
if Not (Assigned(El.Elements) and (El.Elements.Count>0)) then
begin
@ -8834,7 +8835,7 @@ begin
// default else: throw exceptobject
Last.BFalse:=TJSThrowStatement(CreateElement(TJSThrowStatement,El));
TJSThrowStatement(Last.BFalse).A:=
CreatePrimitiveDotExpr(FBuiltInNames[pbivnExceptObject]);
CreatePrimitiveDotExpr(FBuiltInNames[pbivnExceptObject],El);
end;
end
else
@ -9070,7 +9071,7 @@ begin
ImplContext.ThisPas:=El;
ModVarName:=FBuiltInNames[pbivnModule];
AddToSourceElements(Src,CreateVarStatement(ModVarName,
CreatePrimitiveDotExpr('this'),El));
CreatePrimitiveDotExpr('this',El),El));
ImplContext.AddLocalVar(ModVarName,El);
// add var $impl = $mod.$impl
@ -9384,9 +9385,9 @@ var
begin
aName:=GetTypeInfoName(El,AContext,ErrorEl);
if aName=FBuiltInNames[pbivnRTTILocal] then
Result:=CreatePrimitiveDotExpr(aName)
Result:=CreatePrimitiveDotExpr(aName,El)
else if LeftStr(aName,length(FBuiltInNames[pbivnRTL])+1)=FBuiltInNames[pbivnRTL]+'.' then
Result:=CreatePrimitiveDotExpr(aName)
Result:=CreatePrimitiveDotExpr(aName,El)
else
begin
CurEl:=El;
@ -9878,7 +9879,7 @@ begin
if El.ExceptObject<>Nil then
E:=ConvertElement(El.ExceptObject,AContext)
else
E:=CreatePrimitiveDotExpr(FBuiltInNames[pbivnExceptObject]);
E:=CreatePrimitiveDotExpr(FBuiltInNames[pbivnExceptObject],El);
T:=TJSThrowStatement(CreateElement(TJSThrowStatement,El));
T.A:=E;
Result:=T;
@ -10815,7 +10816,7 @@ begin
begin
// aChar -> aChar.charCodeAt()
Call:=TJSCallExpression(CreateElement(TJSCallExpression,Expr));
Call.Expr:=CreateDotExpression(Expr,Result,CreatePrimitiveDotExpr('charCodeAt'));
Call.Expr:=CreateDotExpression(Expr,Result,CreatePrimitiveDotExpr('charCodeAt',Expr));
Result:=Call;
end
else if ExprResolved.BaseType=btContext then
@ -11214,12 +11215,17 @@ function TPasToJSConverter.CreateReferencePathExpr(El: TPasElement;
): TJSElement;
var
Name: String;
Src: TPasElement;
begin
{$IFDEF VerbosePas2JS}
writeln('TPasToJSConverter.CreateReferencePathExpr El="',GetObjName(El),'" El.Parent=',GetObjName(El.Parent));
{$ENDIF}
Name:=CreateReferencePath(El,AContext,rpkPathAndName,Full,Ref);
Result:=CreatePrimitiveDotExpr(Name);
if Ref<>nil then
Src:=Ref.Element
else
Src:=nil;
Result:=CreatePrimitiveDotExpr(Name,Src);
end;
procedure TPasToJSConverter.CreateProcedureCall(var Call: TJSCallExpression;
@ -11467,12 +11473,12 @@ begin
// GetExpr: this.p.readvar
// Will create "{p:GetPathExpr, get:function(){return GetExpr;},
// set:function(v){GetExpr = v;}}"
GetPathExpr:=CreatePrimitiveDotExpr(LeftStr(GetPath,GetDotPos-1));
GetExpr:=CreateDotExpression(El,CreatePrimitiveDotExpr('this.'+GetPathName),
CreatePrimitiveDotExpr(copy(GetPath,GetDotPos+1)));
GetPathExpr:=CreatePrimitiveDotExpr(LeftStr(GetPath,GetDotPos-1),El);
GetExpr:=CreateDotExpression(El,CreatePrimitiveDotExpr('this.'+GetPathName,El),
CreatePrimitiveDotExpr(copy(GetPath,GetDotPos+1),El));
if ParamContext.Setter=nil then
SetExpr:=CreateDotExpression(El,CreatePrimitiveDotExpr('this.'+GetPathName),
CreatePrimitiveDotExpr(copy(GetPath,GetDotPos+1)));
SetExpr:=CreateDotExpression(El,CreatePrimitiveDotExpr('this.'+GetPathName,El),
CreatePrimitiveDotExpr(copy(GetPath,GetDotPos+1),El));
end
else
begin
@ -11480,7 +11486,7 @@ begin
GetExpr:=FullGetter;
FullGetter:=nil;
if ParamContext.Setter=nil then
SetExpr:=CreatePrimitiveDotExpr(GetPath);
SetExpr:=CreatePrimitiveDotExpr(GetPath,El);
end;
if ParamContext.Setter<>nil then
@ -11496,15 +11502,15 @@ begin
if LeftStr(GetPath,GetDotPos)=LeftStr(SetPath,SetDotPos) then
begin
// use GetPathExpr for setter
SetExpr:=CreateDotExpression(El,CreatePrimitiveDotExpr('this.'+GetPathName),
CreatePrimitiveDotExpr(copy(SetPath,GetDotPos+1)));
SetExpr:=CreateDotExpression(El,CreatePrimitiveDotExpr('this.'+GetPathName,El),
CreatePrimitiveDotExpr(copy(SetPath,GetDotPos+1),El));
end
else
begin
// setter needs its own SetPathExpr
SetPathExpr:=CreatePrimitiveDotExpr(LeftStr(SetPath,SetDotPos-1));
SetExpr:=CreateDotExpression(El,CreatePrimitiveDotExpr('this.'+SetPathName),
CreatePrimitiveDotExpr(copy(SetPath,GetDotPos+1)));
SetPathExpr:=CreatePrimitiveDotExpr(LeftStr(SetPath,SetDotPos-1),El);
SetExpr:=CreateDotExpression(El,CreatePrimitiveDotExpr('this.'+SetPathName,El),
CreatePrimitiveDotExpr(copy(SetPath,GetDotPos+1),El));
end;
end;
end;
@ -11523,12 +11529,12 @@ begin
// SetExpr: this.p.i
DotExpr:=TJSDotMemberExpression(FullGetter);
GetPathExpr:=DotExpr.MExpr;
DotExpr.MExpr:=CreatePrimitiveDotExpr('this.'+GetPathName);
DotExpr.MExpr:=CreatePrimitiveDotExpr('this.'+GetPathName,El);
GetExpr:=DotExpr;
FullGetter:=nil;
SetExpr:=CreateDotExpression(El,
CreatePrimitiveDotExpr('this.'+GetPathName),
CreatePrimitiveDotExpr(String(DotExpr.Name)));
CreatePrimitiveDotExpr('this.'+GetPathName,El),
CreatePrimitiveDotExpr(String(DotExpr.Name),El));
end
else if FullGetter.ClassType=TJSBracketMemberExpression then
begin
@ -11544,12 +11550,12 @@ begin
ParamExpr:=BracketExpr.Name;
// create "a:value"
BracketExpr.Name:=CreatePrimitiveDotExpr('this.'+ParamName);
BracketExpr.Name:=CreatePrimitiveDotExpr('this.'+ParamName,El);
AddVar(ParamName,ParamExpr);
// create GetPathExpr "this.arr"
GetPathExpr:=BracketExpr.MExpr;
BracketExpr.MExpr:=CreatePrimitiveDotExpr('this.'+GetPathName);
BracketExpr.MExpr:=CreatePrimitiveDotExpr('this.'+GetPathName,El);
// GetExpr "this.p[this.a]"
GetExpr:=BracketExpr;
@ -11558,8 +11564,8 @@ begin
// SetExpr "this.p[this.a]"
BracketExpr:=TJSBracketMemberExpression(CreateElement(TJSBracketMemberExpression,El));
SetExpr:=BracketExpr;
BracketExpr.MExpr:=CreatePrimitiveDotExpr('this.'+GetPathName);
BracketExpr.Name:=CreatePrimitiveDotExpr('this.'+ParamName);
BracketExpr.MExpr:=CreatePrimitiveDotExpr('this.'+GetPathName,El);
BracketExpr.Name:=CreatePrimitiveDotExpr('this.'+ParamName,El);
end
else
@ -11577,7 +11583,7 @@ begin
// create SetExpr = v;
AssignSt:=TJSSimpleAssignStatement(CreateElement(TJSSimpleAssignStatement,El));
AssignSt.LHS:=SetExpr;
AssignSt.Expr:=CreatePrimitiveDotExpr(TempRefObjSetterArgName);
AssignSt.Expr:=CreatePrimitiveDotExpr(TempRefObjSetterArgName,El);
SetExpr:=AssignSt;
end
else if (SetExpr.ClassType=TJSCallExpression) then
@ -11648,7 +11654,7 @@ begin
// create "T.isPrototypeOf(exceptObject)"
Call:=CreateCallExpression(El);
Call.Expr:=DotExpr;
Call.AddArg(CreatePrimitiveDotExpr(FBuiltInNames[pbivnExceptObject]));
Call.AddArg(CreatePrimitiveDotExpr(FBuiltInNames[pbivnExceptObject],El));
IfSt.Cond:=Call;
if El.VarEl<>nil then
@ -11658,7 +11664,7 @@ begin
ListLast:=ListFirst;
IfSt.BTrue:=ListFirst;
V:=CreateVarStatement(TransformVariableName(El,El.VariableName,AContext),
CreatePrimitiveDotExpr(FBuiltInNames[pbivnExceptObject]),El);
CreatePrimitiveDotExpr(FBuiltInNames[pbivnExceptObject],El),El);
ListFirst.A:=V;
// add statements
AddToStatementList(ListFirst,ListLast,ConvertElement(El.Body,AContext),El);
@ -11867,7 +11873,7 @@ const
VarAssignSt.LHS:=CreateSubDeclNameExpr(PasVar,PasVar.Name,FuncContext);
VarDotExpr:=TJSDotMemberExpression(CreateElement(TJSDotMemberExpression,PasVar));
VarAssignSt.Expr:=VarDotExpr;
VarDotExpr.MExpr:=CreatePrimitiveDotExpr(SrcParamName);
VarDotExpr.MExpr:=CreatePrimitiveDotExpr(SrcParamName,PasVar);
VarDotExpr.Name:=TJSString(TransformVariableName(PasVar,FuncContext));
if (AContext.Resolver<>nil) then
begin
@ -12090,7 +12096,7 @@ begin
IfSt:=TJSIfStatement(CreateElement(TJSIfStatement,El));
AddToStatementList(BodyFirst,BodyLast,IfSt,El);
FD.Body.A:=BodyFirst;
IfSt.Cond:=CreatePrimitiveDotExpr(SrcParamName);
IfSt.Cond:=CreatePrimitiveDotExpr(SrcParamName,El);
// add clone statements
AddCloneStatements(IfSt,FuncContext);
// add init default statements
@ -12120,7 +12126,7 @@ begin
// );
Call2:=CreateCallExpression(El);
Call2.Expr:=CreateDotExpression(El,Call,
CreatePrimitiveDotExpr(FBuiltInNames[pbifnRTTIAddFields]));
CreatePrimitiveDotExpr(FBuiltInNames[pbifnRTTIAddFields],El));
Call:=Call2;
AddRTTIFields(Call.Args,ListFirst,ListLast);
end;

View File

@ -92,6 +92,8 @@ begin
end;
procedure TPas2JSMapper.SetCurElement(const AValue: TJSElement);
var
C: TClass;
begin
{$IFDEF VerboseSrcMap}
system.write('TPas2JSWriter.SetCurElement ',CurLine,',',CurColumn);
@ -101,6 +103,12 @@ begin
system.writeln(' NIL');
{$ENDIF}
inherited SetCurElement(AValue);
C:=AValue.ClassType;
if (C=TJSStatementList)
or (C=TJSEmptyBlockStatement)
or (C=TJSEmptyStatement) then
exit; // do not switch position on brackets
if (AValue<>nil) and (AValue.Source<>'') then
begin
if (FSrcFilename<>AValue.Source)

View File

@ -59,7 +59,8 @@ type
procedure TestIfBegin;
procedure TestFor;
procedure TestFunction;
procedure Test;
procedure TestExternalObjCall;
procedure TestBracketAccessor;
end;
implementation
@ -120,89 +121,12 @@ end;
procedure TCustomTestSrcMap.WriteSrcMapLine(GeneratedLine: integer);
var
JS, Origins, Addition: String;
GeneratedCol: integer; // 0-based
i, diff, GenColStep: Integer;
aSeg: TSourceMapSegment;
JS, Origins: String;
begin
JS:=JSSource[GeneratedLine-1];
Origins:='';
GeneratedCol:=0;// 0-based
i:=SrcMap.IndexOfSegmentAt(GeneratedLine,GeneratedCol);
aSeg:=nil;
if i<0 then
begin
// no segment at line start
i:=0;
if (i=SrcMap.Count) then
aSeg:=nil
else
aSeg:=SrcMap[i];
if (aSeg=nil) or (aSeg.GeneratedLine>GeneratedLine) then
begin
// no segment in line
for i:=1 to length(JS) do Origins:=Origins+'?';
writeln(JS);
writeln(Origins);
exit;
end
else
begin
// show "?" til start of first segment
for i:=1 to aSeg.GeneratedColumn do Origins:=Origins+'?';
end;
end
else
aSeg:=SrcMap[i];
repeat
Addition:='';
if (aSeg.GeneratedLine=GeneratedLine) and (aSeg.GeneratedColumn=GeneratedCol) then
begin
// segment starts here -> write "|line,col"
Addition:='|'+IntToStr(aSeg.SrcLine)+','+IntToStr(aSeg.SrcColumn);
Origins:=Origins+Addition;
end;
inc(i);
// skip segments at same GeneratedLine/Col
while (i<SrcMap.Count) do
begin
aSeg:=SrcMap[i];
if (aSeg.GeneratedLine=GeneratedLine) and (aSeg.GeneratedColumn=GeneratedCol) then
inc(i)
else
break;
end;
if (i=SrcMap.Count) then
aSeg:=nil
else
aSeg:=SrcMap[i];
if (aSeg=nil) or (aSeg.GeneratedLine>GeneratedLine) then
begin
// in the last segment
while length(Origins)<length(JS) do
Origins:=Origins+'.';
writeln(JS);
writeln(Origins);
exit;
end;
// there is another segment in this line
// -> align JS and Origins
GenColStep:=aSeg.GeneratedColumn-GeneratedCol;
diff:=GenColStep-length(Addition);
if diff<0 then
// for example:
// JS: if(~~e)~~~{
// Origins: |12,3|12,5|12,7
Insert(StringOfChar('~',-diff),JS,length(Origins)-length(Addition)+1+GenColStep)
else
while diff>0 do
begin
Origins:=Origins+'.';
dec(diff);
end;
GeneratedCol:=aSeg.GeneratedColumn;
until false;
DebugSrcMapLine(GeneratedLine,JS,SrcMap,Origins);
writeln(JS);
writeln(Origins);
end;
{ TTestSrcMap }
@ -292,9 +216,48 @@ begin
CheckSrcMap('TestFunction');
end;
procedure TTestSrcMap.Test;
procedure TTestSrcMap.TestExternalObjCall;
begin
StartProgram(false);
Add([
'{$modeswitch externalclass}',
'type',
' TJSConsole = class external name ''Console''',
' Public',
' procedure log(Obj1 : JSValue); varargs;',
' end;',
'var console : TJSConsole; external name ''window.console'';',
' xhrstatus: longint;',
'begin',
' console.log(''state'');',
' if xhrstatus=200 then',
' begin',
' xhrstatus:=3;',
' xhrstatus:=4;',
' end;']);
ConvertProgram;
CheckSrcMap('TestExternalObjCall');
end;
procedure TTestSrcMap.TestBracketAccessor;
begin
StartProgram(false);
Add([
'{$modeswitch externalclass}',
'type',
' TJSObject = class external name ''Object''',
' private',
' function GetProperties(Name: String): JSValue; external name ''[]'';',
' Public',
' property Properties[Name: string]: JSValue read GetProperties;',
' end;',
'var Obj : TJSObject;',
' j: JSValue;',
'begin',
' j:=Obj.Properties[''state''];',
' ']);
ConvertProgram;
CheckSrcMap('TestExternalObjCall');
end;
Initialization