From 429438fbb9ed8127d3129ad0bfdec8081afbd05d Mon Sep 17 00:00:00 2001 From: mattias <nc-gaertnma@netcologne.de> Date: Thu, 21 Oct 2021 20:02:22 +0200 Subject: [PATCH] pastojs: fixed clear com interface reference in class field on destroy --- packages/pastojs/src/fppas2js.pp | 37 +++++++++++++++------ packages/pastojs/tests/tcmodules.pas | 48 ++++++++++++++++++++++++---- 2 files changed, 69 insertions(+), 16 deletions(-) diff --git a/packages/pastojs/src/fppas2js.pp b/packages/pastojs/src/fppas2js.pp index 2a1752f131..a19880f74e 100644 --- a/packages/pastojs/src/fppas2js.pp +++ b/packages/pastojs/src/fppas2js.pp @@ -19175,6 +19175,9 @@ var Func: TJSFunctionDeclarationStatement; VarType: TPasType; AssignSt: TJSSimpleAssignStatement; + C: TClass; + ElClass: TPasClassType; + Call: TJSCallExpression; begin // add instance members AncestorIsExternal:=(Ancestor is TPasClassType) and TPasClassType(Ancestor).IsExternal; @@ -19204,13 +19207,29 @@ begin // mfFinalize: clear reference if vmExternal in TPasVariable(P).VarModifiers then continue; VarType:=ClassContext.Resolver.ResolveAliasType(TPasVariable(P).VarType); - if (VarType.ClassType=TPasRecordType) - or (VarType.ClassType=TPasClassType) - or (VarType.ClassType=TPasClassOfType) - or (VarType.ClassType=TPasSetType) - or (VarType.ClassType=TPasProcedureType) - or (VarType.ClassType=TPasFunctionType) - or (VarType.ClassType=TPasArrayType) then + C:=VarType.ClassType; + if (C=TPasClassType) then + begin + ElClass:=TPasClassType(VarType); + if (ElClass.ObjKind=okInterface) and (ElClass.InterfaceType=citCom) then + begin + // rtl.setIntfP(this,"FieldName",null) + Call:=CreateCallExpression(El); + NewEl:=Call; + Call.Expr:=CreateMemberExpression([GetBIName(pbivnRTL),GetBIName(pbifnIntfSetIntfP)]); + Call.AddArg(CreatePrimitiveDotExpr('this',El)); + Call.AddArg(CreateLiteralString(El,TransformElToJSName(P,New_FuncContext))); + Call.AddArg(CreateLiteralNull(El)); + end; + end; + if (NewEl=nil) + and ((C=TPasRecordType) + or (C=TPasClassType) + or (C=TPasClassOfType) + or (C=TPasSetType) + or (C=TPasProcedureType) + or (C=TPasFunctionType) + or (C=TPasArrayType)) then begin // add 'this.FieldName = undefined;' AssignSt:=TJSSimpleAssignStatement(CreateElement(TJSSimpleAssignStatement,El)); @@ -21123,7 +21142,7 @@ begin Result:=Call; if LHS is TJSDotMemberExpression then begin - // path.name = RHS -> rtl.setIntfP(path,"IntfVar",RHS}) + // path.name = RHS -> rtl.setIntfP(path,"IntfVar",RHS) Call.Expr:=CreateMemberExpression([GetBIName(pbivnRTL),GetBIName(pbifnIntfSetIntfP)]); Call.AddArg(TJSDotMemberExpression(LHS).MExpr); TJSDotMemberExpression(LHS).MExpr:=nil; @@ -21136,7 +21155,7 @@ begin end else if LHS is TJSBracketMemberExpression then begin - // path[index] = RHS -> rtl.setIntfP(path,index,RHS}) + // path[index] = RHS -> rtl.setIntfP(path,index,RHS) Call.Expr:=CreateMemberExpression([GetBIName(pbivnRTL),GetBIName(pbifnIntfSetIntfP)]); Call.AddArg(TJSBracketMemberExpression(LHS).MExpr); TJSBracketMemberExpression(LHS).MExpr:=nil; diff --git a/packages/pastojs/tests/tcmodules.pas b/packages/pastojs/tests/tcmodules.pas index 66b51538b6..73e8e8dc84 100644 --- a/packages/pastojs/tests/tcmodules.pas +++ b/packages/pastojs/tests/tcmodules.pas @@ -20,7 +20,7 @@ unit TCModules; {$mode objfpc}{$H+} - +{$Optimization } interface uses @@ -910,10 +910,9 @@ type // Library Procedure TestLibrary_Empty; - Procedure TestLibrary_ExportFunc; // ToDo - // ToDo: export let as let fail - // ToDo: Procedure TestLibrary_ExportVar; - // ToDo: Procedure TestLibrary_Export_Index_Fail; + Procedure TestLibrary_ExportFunc; + Procedure TestLibrary_Export_Index_Fail; + Procedure TestLibrary_ExportVar; // ToDo // ToDo: test delayed specialization init // ToDo: analyzer end; @@ -20885,7 +20884,7 @@ begin ' this.FAnt = null;', ' };', ' this.$final = function () {', - ' this.FAnt = undefined;', + ' rtl.setIntfP(this, "FAnt", null);', ' };', ' rtl.addIntf(this, $mod.IUnknown);', '});', @@ -21063,7 +21062,7 @@ begin ' this.FDoveObj = null;', ' };', ' this.$final = function () {', - ' this.FBirdIntf = undefined;', + ' rtl.setIntfP(this, "FBirdIntf", null);', ' this.FDoveObj = undefined;', ' $mod.TObject.$final.call(this);', ' };', @@ -33821,6 +33820,41 @@ begin CheckResolverUnexpectedHints(); end; +procedure TTestModule.TestLibrary_Export_Index_Fail; +begin + StartLibrary(false); + Add([ + 'procedure Run(w: word);', + 'begin', + 'end;', + 'exports', + ' Run index 3;', + '']); + SetExpectedPasResolverError('Not supported: export index',nNotSupportedX); + ConvertLibrary; +end; + +procedure TTestModule.TestLibrary_ExportVar; +begin + exit; + + StartLibrary(false); + Add([ + 'var Wing: word;', + 'exports', + ' Wing;', + '']); + ConvertLibrary; + CheckSource('TestLibrary_ExportVar', + LinesToStr([ // statements + 'this.Wing = 0;', + 'export { this.Wing as Wing };', + '']), + LinesToStr([ + ''])); + CheckResolverUnexpectedHints(); +end; + Initialization RegisterTests([TTestModule]); end.