Browse Source

pastojs: external record field

git-svn-id: trunk@39303 -
Mattias Gaertner 7 years ago
parent
commit
5c0a27a974
2 changed files with 44 additions and 3 deletions
  1. 8 3
      packages/pastojs/src/fppas2js.pp
  2. 36 0
      packages/pastojs/tests/tcmodules.pas

+ 8 - 3
packages/pastojs/src/fppas2js.pp

@@ -2782,7 +2782,7 @@ end;
 procedure TPas2JSResolver.FinishVariable(El: TPasVariable);
 const
   ClassFieldModifiersAllowed = [vmClass,vmStatic,vmExternal,vmPublic];
-  RecordVarModifiersAllowed = [];
+  RecordVarModifiersAllowed = [vmExternal];
   LocalVarModifiersAllowed = [];
   ImplementationVarModifiersAllowed = [vmExternal];
   SectionVarModifiersAllowed = [vmExternal,vmPublic];
@@ -2882,6 +2882,9 @@ begin
     RaiseVarModifierNotSupported(RecordVarModifiersAllowed);
     if IsInterfaceType(El.VarType,citCom) then
       RaiseMsg(20180404135105,nNotSupportedX,sNotSupportedX,['COM-interface as record member'],El);
+    if (El.ClassType=TPasConst) and (TPasConst(El).Expr<>nil) then
+      // external const with expression is not writable
+      TPasConst(El).IsConst:=true;
     end
   else if ParentC=TProcedureBody then
     begin
@@ -18348,6 +18351,7 @@ const
     First, Last: TJSStatementList;
     VarDotExpr: TJSDotMemberExpression;
     PasVarType: TPasType;
+    VarName: String;
   begin
     // init members with s
     First:=nil;
@@ -18357,15 +18361,16 @@ const
       PasVar:=TPasVariable(El.Members[i]);
       if not IsElementUsed(PasVar) then continue;
       // create 'this.A = s.A;'
+      VarName:=TransformVariableName(PasVar,FuncContext);
       VarAssignSt:=TJSSimpleAssignStatement(CreateElement(TJSSimpleAssignStatement,PasVar));
       AddToStatementList(First,Last,VarAssignSt,PasVar);
       if IfSt.BTrue=nil then
         IfSt.BTrue:=First;
-      VarAssignSt.LHS:=CreateSubDeclNameExpr(PasVar,PasVar.Name,FuncContext);
+      VarAssignSt.LHS:=CreateSubDeclNameExpr(PasVar,VarName,FuncContext);
       VarDotExpr:=TJSDotMemberExpression(CreateElement(TJSDotMemberExpression,PasVar));
       VarAssignSt.Expr:=VarDotExpr;
       VarDotExpr.MExpr:=CreatePrimitiveDotExpr(SrcParamName,PasVar);
-      VarDotExpr.Name:=TJSString(TransformVariableName(PasVar,FuncContext));
+      VarDotExpr.Name:=TJSString(VarName);
       if (AContext.Resolver<>nil) then
         begin
         PasVarType:=AContext.Resolver.ResolveAliasType(PasVar.VarType);

+ 36 - 0
packages/pastojs/tests/tcmodules.pas

@@ -409,6 +409,7 @@ type
     // record
     Procedure TestRecord_Empty;
     Procedure TestRecord_Var;
+    Procedure TestRecord_VarExternal;
     Procedure TestWithRecordDo;
     Procedure TestRecord_Assign;
     Procedure TestRecord_PassAsArgClone;
@@ -8195,6 +8196,41 @@ begin
     ]));
 end;
 
+procedure TTestModule.TestRecord_VarExternal;
+begin
+  StartProgram(false);
+  Add([
+  '{$modeswitch externalclass}',
+  'type',
+  '  TRecA = record',
+  '    i: byte;',
+  '    length_: longint external name ''length'';',
+  '  end;',
+  'var Rec: TRecA;',
+  'begin',
+  '  rec.length_ := rec.length_',
+  '']);
+  ConvertProgram;
+  CheckSource('TestRecord_VarExternal',
+    LinesToStr([ // statements
+    'this.TRecA = function (s) {',
+    '  if (s) {',
+    '    this.i = s.i;',
+    '    this.length = s.length;',
+    '  } else {',
+    '    this.i = 0;',
+    '  };',
+    '  this.$equal = function (b) {',
+    '    return (this.i === b.i) && (this.length === b.length);',
+    '  };',
+    '};',
+    'this.Rec = new $mod.TRecA();',
+    '']),
+    LinesToStr([ // $mod.$main
+    '$mod.Rec.length = $mod.Rec.length;'
+    ]));
+end;
+
 procedure TTestModule.TestWithRecordDo;
 begin
   StartProgram(false);