pastojs: external record field

git-svn-id: trunk@39303 -
This commit is contained in:
Mattias Gaertner 2018-06-25 16:05:40 +00:00
parent 936a26ed29
commit 5c0a27a974
2 changed files with 44 additions and 3 deletions

View File

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

View File

@ -409,6 +409,7 @@ type
// record // record
Procedure TestRecord_Empty; Procedure TestRecord_Empty;
Procedure TestRecord_Var; Procedure TestRecord_Var;
Procedure TestRecord_VarExternal;
Procedure TestWithRecordDo; Procedure TestWithRecordDo;
Procedure TestRecord_Assign; Procedure TestRecord_Assign;
Procedure TestRecord_PassAsArgClone; Procedure TestRecord_PassAsArgClone;
@ -8195,6 +8196,41 @@ begin
])); ]));
end; 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; procedure TTestModule.TestWithRecordDo;
begin begin
StartProgram(false); StartProgram(false);