Browse Source

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

git-svn-id: trunk@37264 -
Mattias Gaertner 8 years ago
parent
commit
77b1cfcd0d

+ 1 - 1
packages/fcl-passrc/src/pasresolveeval.pas

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

+ 76 - 70
packages/pastojs/src/fppas2js.pp

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

+ 8 - 0
packages/pastojs/src/fppjssrcmap.pp

@@ -92,6 +92,8 @@ begin
 end;
 end;
 
 
 procedure TPas2JSMapper.SetCurElement(const AValue: TJSElement);
 procedure TPas2JSMapper.SetCurElement(const AValue: TJSElement);
+var
+  C: TClass;
 begin
 begin
   {$IFDEF VerboseSrcMap}
   {$IFDEF VerboseSrcMap}
   system.write('TPas2JSWriter.SetCurElement ',CurLine,',',CurColumn);
   system.write('TPas2JSWriter.SetCurElement ',CurLine,',',CurColumn);
@@ -101,6 +103,12 @@ begin
     system.writeln(' NIL');
     system.writeln(' NIL');
   {$ENDIF}
   {$ENDIF}
   inherited SetCurElement(AValue);
   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
   if (AValue<>nil) and (AValue.Source<>'') then
     begin
     begin
     if (FSrcFilename<>AValue.Source)
     if (FSrcFilename<>AValue.Source)

+ 46 - 83
packages/pastojs/tests/tcsrcmap.pas

@@ -59,7 +59,8 @@ type
     procedure TestIfBegin;
     procedure TestIfBegin;
     procedure TestFor;
     procedure TestFor;
     procedure TestFunction;
     procedure TestFunction;
-    procedure Test;
+    procedure TestExternalObjCall;
+    procedure TestBracketAccessor;
   end;
   end;
 
 
 implementation
 implementation
@@ -120,89 +121,12 @@ end;
 
 
 procedure TCustomTestSrcMap.WriteSrcMapLine(GeneratedLine: integer);
 procedure TCustomTestSrcMap.WriteSrcMapLine(GeneratedLine: integer);
 var
 var
-  JS, Origins, Addition: String;
-  GeneratedCol: integer; // 0-based
-  i, diff, GenColStep: Integer;
-  aSeg: TSourceMapSegment;
+  JS, Origins: String;
 begin
 begin
   JS:=JSSource[GeneratedLine-1];
   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;
 end;
 
 
 { TTestSrcMap }
 { TTestSrcMap }
@@ -292,9 +216,48 @@ begin
   CheckSrcMap('TestFunction');
   CheckSrcMap('TestFunction');
 end;
 end;
 
 
-procedure TTestSrcMap.Test;
+procedure TTestSrcMap.TestExternalObjCall;
 begin
 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;
 end;
 
 
 Initialization
 Initialization