pastojs: filer: add identifiers to scope for immediate specializations of TPasSpecializeType

This commit is contained in:
mattias 2020-11-29 23:12:51 +00:00
parent 84321a4c29
commit ade8d75bb0
3 changed files with 202 additions and 115 deletions

View File

@ -872,6 +872,7 @@ type
public
constructor Create; override;
destructor Destroy; override;
procedure ClearIdentifiers(FreeItems: boolean);
function FindLocalIdentifier(const Identifier: String): TPasIdentifier; inline;
function FindIdentifier(const Identifier: String): TPasIdentifier; virtual;
function RemoveLocalIdentifier(El: TPasElement): boolean; virtual;
@ -4412,22 +4413,37 @@ end;
destructor TPasIdentifierScope.Destroy;
begin
{$IFDEF VerbosePasResolverMem}
writeln('TPasIdentifierScope.Destroy START ',ClassName);
{$ENDIF}
FItems.ForEachCall(@OnClearItem,nil);
{$ifdef pas2js}
FItems:=nil;
{$else}
FItems.Clear;
FreeAndNil(FItems);
{$endif}
ClearIdentifiers(true);
inherited Destroy;
{$IFDEF VerbosePasResolverMem}
writeln('TPasIdentifierScope.Destroy END ',ClassName);
{$ENDIF}
end;
procedure TPasIdentifierScope.ClearIdentifiers(FreeItems: boolean);
begin
{$IFDEF VerbosePasResolverMem}
writeln('TPasIdentifierScope.Clear START ',ClassName);
{$ENDIF}
FItems.ForEachCall(@OnClearItem,nil);
{$ifdef pas2js}
if FreeItems then
FItems:=nil
else
FItems.Clear;
{$else}
FItems.Clear;
if FreeItems then
FreeAndNil(FItems);
{$endif}
{$IFDEF VerbosePasResolverMem}
writeln('TPasIdentifierScope.Clear END ',ClassName);
{$ENDIF}
end;
function TPasIdentifierScope.FindIdentifier(const Identifier: String
): TPasIdentifier;
begin

View File

@ -5204,7 +5204,12 @@ begin
// set AncestorScope
aClassAncestor:=Resolver.ResolveAliasType(Scope.DirectAncestor);
if not (aClassAncestor is TPasClassType) then
begin
{$IFDEF VerbosePCUFiler}
writeln('TPCUReader.Set_ClassScope_DirectAncestor ',GetObjPath(Scope.DirectAncestor),' ClassAnc=',GetObjPath(aClassAncestor));
{$ENDIF}
RaiseMsg(20180214114322,Scope.Element,GetObjName(RefEl));
end;
AncestorScope:=aClassAncestor.CustomData as TPas2JSClassScope;
Scope.AncestorScope:=AncestorScope;
if (AncestorScope<>nil) and (pcsfPublished in Scope.AncestorScope.Flags) then
@ -6649,6 +6654,8 @@ end;
procedure TPCUReader.ReadSpecialization(Obj: TJSONObject;
GenEl: TPasGenericType; ParamIDs: TJSONArray);
// called by ReadSpecializations
// create a specialization promise
var
i, Id: Integer;
ErrorEl: TPasElement;
@ -6905,6 +6912,8 @@ begin
if Section.PendingUsedIntf<>nil then
RaiseMsg(20180308160639,Section,GetObjName(Section.PendingUsedIntf));
end;
Resolver.PushScope(Scope);
try
// read external references
ReadUsedUnitsFinish(Obj,Section,aContext);
// read scope, needs external refs
@ -6913,6 +6922,9 @@ begin
aContext.ModeSwitches:=Scope.ModeSwitches;
// read declarations, needs external refs
ReadDeclarations(Obj,Section,aContext);
finally
Resolver.PopScope;
end;
Scope.Finished:=true;
if Section is TInterfaceSection then
@ -6968,10 +6980,31 @@ end;
function TPCUReader.CreateElement(AClass: TPTreeElement; const AName: String;
AParent: TPasElement): TPasElement;
var
Scope: TPasScope;
Kind: TPasIdentifierKind;
begin
Result:=AClass.Create(AName,AParent);
Result.SourceFilename:=SourceFilename;
{$IFDEF CheckPasTreeRefCount}Result.RefIds.Add('CreateElement');{$ENDIF}
if (AName<>'')
and (AClass<>TPasArgument)
and (AClass<>TPasResultElement)
and (AClass<>TPasGenericTemplateType) then
begin
Scope:=Resolver.TopScope;
if Scope is TPasIdentifierScope then
begin
// add identifier to scope
// Note: Resolver needs this for specializations
// The scope identifiers will be later replaced with the values from the
// pcu, see ResolvePendingIdentifierScopes
Kind:=PCUDefaultIdentifierKind;
if Result is TPasProcedure then
Kind:=pikProc;
TPasIdentifierScope(Scope).AddIdentifier(AName,Result,Kind);
end;
end;
end;
function TPCUReader.ReadElementProperty(Obj: TJSONObject; Parent: TPasElement;
@ -7455,8 +7488,9 @@ var
Ref: TPCUFilerElementRef;
begin
{$IFDEF VerbosePCUFiler}
writeln('TPCUReader.ReadIdentifierScope ',Arr.Count);
writeln('TPCUReader.ReadIdentifierScopeArray ',Arr.Count);
{$ENDIF}
Scope.ClearIdentifiers(false);
for i:=0 to Arr.Count-1 do
begin
Data:=Arr[i];
@ -7465,7 +7499,7 @@ begin
Id:=Data.AsInteger;
Ref:=GetElRef(Id,DefKind,DefName);
{$IFDEF VerbosePCUFiler}
writeln('TPCUReader.ReadIdentifierScope Id=',Id,' ',DefName,' ',DefKind,' ',GetObjName(Ref.Element));
writeln('TPCUReader.ReadIdentifierScopeArray Id=',Id,' ',DefName,' ',DefKind,' ',GetObjName(Ref.Element));
{$ENDIF}
Scope.AddIdentifier(DefName,Ref.Element,DefKind);
end
@ -8245,6 +8279,7 @@ var
SpecName: string;
i, SpecId: Integer;
Data: TPasSpecializeTypeData;
PendSpec: TPCUReaderPendingSpecialized;
begin
ReadAliasType(Obj,El,aContext);
if not (El.DestType is TPasGenericType) then
@ -8280,7 +8315,11 @@ begin
RaiseMsg(20200530134152,El);
if Data.SpecializedType=nil then
PromiseSpecialize(SpecId,SpecName,El,El);
begin
PendSpec:=PromiseSpecialize(SpecId,SpecName,El,El);
// specialize now
CreateSpecializedElement(PendSpec);
end;
end;
procedure TPCUReader.ReadInlineSpecializeExpr(Obj: TJSONObject;
@ -8372,9 +8411,14 @@ begin
ReadPasElement(Obj,El,aContext);
ReadEnumTypeScope(Obj,Scope,aContext);
Resolver.PushScope(Scope);
try
ReadElementList(Obj,El,'Values',El.Values,
{$IFDEF CheckPasTreeRefCount}'TPasEnumType.Values'{$ELSE}true{$ENDIF},
aContext);
finally
Resolver.PopScope;
end;
end;
procedure TPCUReader.ReadSetType(Obj: TJSONObject; El: TPasSetType;
@ -8433,6 +8477,9 @@ begin
ReadPasElement(Obj,El,aContext);
ReadGenericTemplateTypes(Obj,El,El.GenericTemplateTypes,aContext);
El.PackMode:=ReadPackedMode(Obj,'Packed',El);
Resolver.PushScope(Scope);
try
ReadElementList(Obj,El,'Members',El.Members,
{$IFDEF CheckPasTreeRefCount}'TPasRecordType.Members'{$ELSE}true{$ENDIF},
aContext);
@ -8454,7 +8501,9 @@ begin
ReadElementList(Obj,El,'Variants',El.Variants,
{$IFDEF CheckPasTreeRefCount}'TPasRecordType.Variants'{$ELSE}true{$ENDIF},
aContext);
finally
Resolver.PopScope;
end;
ReadRecordScope(Obj,Scope,aContext);
Resolver.FinishSpecializedClassOrRecIntf(Scope);
Resolver.FinishSpecializations(Scope);
@ -8796,6 +8845,8 @@ begin
if Scope<>nil then
begin
Resolver.PushScope(Scope);
try
ReadClassScope(Obj,Scope,aContext);
// read Members
@ -8822,7 +8873,9 @@ begin
Parent:=Parent.Parent;
end;
end;
finally
Resolver.PopScope;
end;
Resolver.FinishSpecializedClassOrRecIntf(Scope);
Resolver.FinishSpecializations(Scope);
ReadSpecializations(Obj,El);
@ -8909,6 +8962,14 @@ var
begin
ReadPasElement(Obj,El,aContext);
ReadGenericTemplateTypes(Obj,El,El.GenericTemplateTypes,aContext);
if (El.GenericTemplateTypes<>nil) and (El.GenericTemplateTypes.Count>0) then
begin
Scope:=TPas2JSProcTypeScope(Resolver.CreateScope(El,TPas2JSProcTypeScope));
El.CustomData:=Scope;
ReadProcTypeScope(Obj,Scope,aContext);
end;
ReadElementList(Obj,El,'Args',El.Args,
{$IFDEF CheckPasTreeRefCount}'TPasProcedureType.Args'{$ELSE}true{$ENDIF},
aContext);
@ -8928,13 +8989,6 @@ begin
end;
El.Modifiers:=ReadProcTypeModifiers(Obj,El,'Modifiers',GetDefaultProcTypeModifiers(El));
if (El.GenericTemplateTypes<>nil) and (El.GenericTemplateTypes.Count>0) then
begin
Scope:=TPas2JSProcTypeScope(Resolver.CreateScope(El,TPas2JSProcTypeScope));
El.CustomData:=Scope;
ReadProcTypeScope(Obj,Scope,aContext);
end;
ReadSpecializations(Obj,El);
end;
@ -9065,9 +9119,17 @@ begin
El.DispIDExpr:=ReadExpr(Obj,El,'DispId',aContext);
El.StoredAccessor:=ReadExpr(Obj,El,'Stored',aContext);
El.DefaultExpr:=ReadExpr(Obj,El,'DefaultValue',aContext);
if Scope<>nil then
Resolver.PushScope(Scope);
try
ReadElementList(Obj,El,'Args',El.Args,
{$IFDEF CheckPasTreeRefCount}'TPasProperty.Args'{$ELSE}true{$ENDIF},
aContext);
finally
if Scope<>nil then
Resolver.PopScope;
end;
//ReadAccessorName: string; // not used by resolver
//WriteAccessorName: string; // not used by resolver
//ImplementsName: string; // not used by resolver
@ -9298,6 +9360,8 @@ begin
if DeclProc=nil then
DeclProc:=El;
Resolver.PushScope(ImplScope);
try
if Resolver.ProcCanBePrecompiled(DeclProc) then
begin
// normal proc (non generic)
@ -9333,6 +9397,9 @@ begin
aContext.InGeneric:=OldInGeneric;
end;
end;
finally
Resolver.PopScope;
end;
end;
procedure TPCUReader.ReadProcedure(Obj: TJSONObject; El: TPasProcedure;

View File

@ -2359,19 +2359,22 @@ var
begin
WithTypeInfo:=true;
StartProgram(true);
Add('type');
Add(' TArrA = array of char;');
Add(' TArrB = array of string;');
Add(' TObject = class');
Add(' public');
Add(' PublicA: TArrA;');
Add(' published');
Add(' PublishedB: TArrB;');
Add(' end;');
Add('var');
Add(' C: TObject;');
Add('begin');
Add(' C.PublicA:=nil;');
Add([
'type',
' TArrA = array of char;',
' TArrB = array of string;',
' TObject = class',
' public',
' PublicA: TArrA;',
' published',
' PublishedB: TArrB;',
' end;',
'var',
' C: TObject;',
'begin',
' C.PublicA:=nil;',
' if typeinfo(TObject)=nil then ;',
'']);
ConvertProgram;
ActualSrc:=ConvertJSModuleToString(JSModule);
ExpectedSrc:=LinesToStr([
@ -2395,6 +2398,7 @@ begin
' this.C = null;',
' $mod.$main = function () {',
' $mod.C.PublicA = [];',
' if ($mod.$rtti["TObject"] === null) ;',
' };',
'});',
'']);