pastojs: filer: class in other unit

git-svn-id: trunk@38479 -
This commit is contained in:
Mattias Gaertner 2018-03-10 10:17:33 +00:00
parent b2e21f4c4a
commit 787b2a2e05
3 changed files with 292 additions and 57 deletions

View File

@ -58,6 +58,8 @@ const
PJUMagic = 'Pas2JSCache'; PJUMagic = 'Pas2JSCache';
PJUVersion = 1; PJUVersion = 1;
BuiltInNodeName = 'BuiltIn';
PJUDefaultParserOptions: TPOptions = po_Pas2js; PJUDefaultParserOptions: TPOptions = po_Pas2js;
PJUBoolStr: array[boolean] of string = ( PJUBoolStr: array[boolean] of string = (
@ -792,6 +794,7 @@ type
procedure ReadSrcFiles(Data: TJSONData); virtual; procedure ReadSrcFiles(Data: TJSONData); virtual;
function ReadMemberHints(Obj: TJSONObject; El: TPasElement; const DefaultValue: TPasMemberHints): TPasMemberHints; virtual; function ReadMemberHints(Obj: TJSONObject; El: TPasElement; const DefaultValue: TPasMemberHints): TPasMemberHints; virtual;
procedure ReadPasElement(Obj: TJSONObject; El: TPasElement; aContext: TPJUReaderContext); virtual; procedure ReadPasElement(Obj: TJSONObject; El: TPasElement; aContext: TPJUReaderContext); virtual;
procedure ReadExtRefs(Obj: TJSONObject; El: TPasElement); virtual;
procedure ReadUsedUnits(Obj: TJSONObject; Section: TPasSection; aContext: TPJUReaderContext); virtual; procedure ReadUsedUnits(Obj: TJSONObject; Section: TPasSection; aContext: TPJUReaderContext); virtual;
procedure ReadSectionScope(Obj: TJSONObject; Scope: TPasSectionScope; aContext: TPJUReaderContext); virtual; procedure ReadSectionScope(Obj: TJSONObject; Scope: TPasSectionScope; aContext: TPJUReaderContext); virtual;
procedure ReadSection(Obj: TJSONObject; Section: TPasSection; aContext: TPJUReaderContext); virtual; procedure ReadSection(Obj: TJSONObject; Section: TPasSection; aContext: TPJUReaderContext); virtual;
@ -1216,7 +1219,7 @@ procedure TPJUFilerElementRef.Clear;
var var
Ref, NextRef: TPJUFilerPendingElRef; Ref, NextRef: TPJUFilerPendingElRef;
begin begin
FreeAndNil(Elements); Elements:=nil;
Ref:=Pending; Ref:=Pending;
while Ref<>nil do while Ref<>nil do
begin begin
@ -1225,6 +1228,7 @@ begin
Ref.Free; Ref.Free;
Ref:=NextRef; Ref:=NextRef;
end; end;
Pending:=nil;
end; end;
destructor TPJUFilerElementRef.Destroy; destructor TPJUFilerElementRef.Destroy;
@ -1955,7 +1959,7 @@ procedure TPJUWriter.WriteSection(ParentJSON: TJSONObject;
var var
Obj, SubObj: TJSONObject; Obj, SubObj: TJSONObject;
Scope, UsesScope: TPasSectionScope; Scope, UsesScope: TPasSectionScope;
i: Integer; i, j: Integer;
Arr: TJSONArray; Arr: TJSONArray;
UsesUnit: TPasUsesUnit; UsesUnit: TPasUsesUnit;
Name, InFilename: String; Name, InFilename: String;
@ -1976,16 +1980,28 @@ begin
begin begin
UsesUnit:=Section.UsesClause[i]; UsesUnit:=Section.UsesClause[i];
UsesScope:=TPasSectionScope(Scope.UsesScopes[i]); UsesScope:=TPasSectionScope(Scope.UsesScopes[i]);
if UsesScope.Element<>UsesUnit.Module then if UsesScope.Element<>TPasModule(UsesUnit.Module).InterfaceSection then
RaiseMsg(20180206122459,Section,'usesscope '+IntToStr(i)+' UsesScope.Element='+GetObjName(UsesScope.Element)+' Module='+GetObjName(Section.UsesClause[i].Module)); RaiseMsg(20180206122459,Section,'usesscope '+IntToStr(i)+' UsesScope.Element='+GetObjName(UsesScope.Element)+' Module='+GetObjName(Section.UsesClause[i].Module));
if Arr=nil then if Arr=nil then
begin begin
Arr:=TJSONArray.Create; Arr:=TJSONArray.Create;
ParentJSON.Add('Uses',Arr); Obj.Add('Uses',Arr);
end; end;
SubObj:=TJSONObject.Create; SubObj:=TJSONObject.Create;
Arr.Add(SubObj); Arr.Add(SubObj);
Name:=DotExprToName(UsesUnit.Expr); if UsesUnit.Expr<>nil then
Name:=DotExprToName(UsesUnit.Expr)
else
begin
// implicit unit, e.g. system
Name:=UsesUnit.Module.Name;
for j:=0 to Parser.ImplicitUses.Count-1 do
if CompareText(Parser.ImplicitUses[i],Name)=0 then
begin
Name:=Parser.ImplicitUses[i];
break;
end;
end;
if Name='' then if Name='' then
RaiseMsg(20180307091654,UsesUnit.Expr); RaiseMsg(20180307091654,UsesUnit.Expr);
SubObj.Add('Name',Name); SubObj.Add('Name',Name);
@ -2008,7 +2024,7 @@ begin
if Ref.Obj=nil then if Ref.Obj=nil then
begin begin
Ref.Obj:=TJSONObject.Create; Ref.Obj:=TJSONObject.Create;
SubObj.Add('Refs',Ref.Obj); SubObj.Add('Module',Ref.Obj);
end; end;
end; end;
end; end;
@ -2477,7 +2493,6 @@ var
Arr: TJSONArray; Arr: TJSONArray;
i: Integer; i: Integer;
PSRef: TPasScopeReference; PSRef: TPasScopeReference;
Ref: TPJUFilerElementRef;
SubObj: TJSONObject; SubObj: TJSONObject;
begin begin
if References=nil then exit; if References=nil then exit;
@ -2490,9 +2505,6 @@ begin
for i:=0 to Refs.Count-1 do for i:=0 to Refs.Count-1 do
begin begin
PSRef:=TPasScopeReference(Refs[i]); PSRef:=TPasScopeReference(Refs[i]);
Ref:=GetElementReference(PSRef.Element);
if (Ref.Id=0) and not (Ref.Element is TPasUnresolvedSymbolRef) then
RaiseMsg(20180221170307,References.Scope.Element,GetObjName(Ref.Element));
SubObj:=TJSONObject.Create; SubObj:=TJSONObject.Create;
Arr.Add(SubObj); Arr.Add(SubObj);
if PSRef.Access<>PJUDefaultPSRefAccess then if PSRef.Access<>PJUDefaultPSRefAccess then
@ -3030,6 +3042,21 @@ end;
procedure TPJUWriter.WriteExternalReferences(ParentJSON: TJSONObject); procedure TPJUWriter.WriteExternalReferences(ParentJSON: TJSONObject);
procedure WriteMemberIndex(Members: TFPList; Member: TPasElement; Obj: TJSONObject);
var
i, Index: Integer;
begin
for i:=0 to Members.Count-1 do
if TPasElement(Members[i])=Member then
begin
Index:=i;
break;
end;
if Index<0 then
RaiseMsg(20180309184111,Member);
Obj.Add('Index',Index);
end;
function WriteExternalRef(El: TPasElement): TPJUFilerElementRef; function WriteExternalRef(El: TPasElement): TPJUFilerElementRef;
var var
ParentRef, Ref: TPJUFilerElementRef; ParentRef, Ref: TPJUFilerElementRef;
@ -3038,12 +3065,6 @@ procedure TPJUWriter.WriteExternalReferences(ParentJSON: TJSONObject);
begin begin
Result:=nil; Result:=nil;
if El=nil then exit; if El=nil then exit;
if El.ClassType=TInterfaceSection then
begin
// skip to module
Result:=WriteExternalRef(El.GetModule);
exit;
end;
// check if already written // check if already written
Ref:=GetElementReference(El); Ref:=GetElementReference(El);
if Ref.Obj<>nil then if Ref.Obj<>nil then
@ -3053,15 +3074,37 @@ procedure TPJUWriter.WriteExternalReferences(ParentJSON: TJSONObject);
ParentRef:=WriteExternalRef(Parent); ParentRef:=WriteExternalRef(Parent);
if ParentRef=nil then if ParentRef=nil then
if not (El is TPasModule) then if not (El is TPasModule) then
RaiseMsg(20180308174440,GetObjName(El)); RaiseMsg(20180308174440,El,GetObjName(El));
// check name // check name
Name:=El.Name; Name:=El.Name;
if Name='' then if Name='' then
RaiseMsg(20180308174850,GetObjName(El)); if El is TInterfaceSection then
Name:='Interface'
else
RaiseMsg(20180308174850,El,GetObjName(El));
// write // write
Ref.Obj:=TJSONObject.Create; Ref.Obj:=TJSONObject.Create;
Ref.Obj.Add('Name',Name);
if ParentRef<>nil then if ParentRef<>nil then
begin begin
// add member index
if Parent is TPasDeclarations then
WriteMemberIndex(TPasDeclarations(Parent).Declarations,El,Ref.Obj)
else if Parent is TPasClassType then
WriteMemberIndex(TPasClassType(Parent).Members,El,Ref.Obj)
else if Parent is TPasRecordType then
WriteMemberIndex(TPasRecordType(Parent).Members,El,Ref.Obj)
else if Parent is TPasEnumType then
WriteMemberIndex(TPasEnumType(Parent).Values,El,Ref.Obj)
else if Parent is TPasModule then
begin
if El is TInterfaceSection then
else
RaiseMsg(20180310104857,Parent,GetObjName(El));
end
else
RaiseMsg(20180310104810,Parent,GetObjName(El));
// add to parent
if ParentRef.Elements=nil then if ParentRef.Elements=nil then
begin begin
ParentRef.Elements:=TJSONArray.Create; ParentRef.Elements:=TJSONArray.Create;
@ -3069,7 +3112,7 @@ procedure TPJUWriter.WriteExternalReferences(ParentJSON: TJSONObject);
end; end;
ParentRef.Elements.Add(Ref.Obj); ParentRef.Elements.Add(Ref.Obj);
end; end;
Ref.Obj.Add('Name',Name); Result:=Ref;
end; end;
var var
@ -3092,13 +3135,13 @@ begin
Data:=El.CustomData; Data:=El.CustomData;
if Data is TResElDataBuiltInSymbol then if Data is TResElDataBuiltInSymbol then
begin begin
// add built-in symbol to System array // add built-in symbol to BuildIn array
if El<>Resolver.FindLocalBuiltInSymbol(El) then if El<>Resolver.FindLocalBuiltInSymbol(El) then
RaiseMsg(20180207124914,El); RaiseMsg(20180207124914,El);
if SystemArr=nil then if SystemArr=nil then
begin begin
SystemArr:=TJSONArray.Create; SystemArr:=TJSONArray.Create;
ParentJSON.Add('System',SystemArr); ParentJSON.Add(BuiltInNodeName,SystemArr);
end; end;
Obj:=TJSONObject.Create; Obj:=TJSONObject.Create;
SystemArr.Add(Obj); SystemArr.Add(Obj);
@ -3116,9 +3159,8 @@ begin
if Ref.Element.GetModule=Resolver.RootElement then if Ref.Element.GetModule=Resolver.RootElement then
RaiseMsg(20180207115645,Ref.Element); // an element of this module was not written RaiseMsg(20180207115645,Ref.Element); // an element of this module was not written
// external element // external element
if Ref.Obj<>nil then if Ref.Obj=nil then
continue; // already written WriteExternalRef(El);
Ref:=WriteExternalRef(El);
// Ref.Id is written in ResolvePendingElRefs // Ref.Id is written in ResolvePendingElRefs
ResolvePendingElRefs(Ref); ResolvePendingElRefs(Ref);
end; end;
@ -4307,19 +4349,97 @@ begin
if aContext<>nil then ; if aContext<>nil then ;
end; end;
procedure TPJUReader.ReadExtRefs(Obj: TJSONObject; El: TPasElement);
procedure ReadMembers(Arr: TJSONArray; Members: TFPList);
var
i, Index: Integer;
Data: TJSONData;
SubObj: TJSONObject;
Name: string;
ChildEl: TPasElement;
begin
for i:=0 to Arr.Count-1 do
begin
Data:=Arr[i];
if not (Data is TJSONObject) then
RaiseMsg(20180309173351,El);
SubObj:=TJSONObject(Data);
// search element
if not ReadString(SubObj,'Name',Name,El) then
RaiseMsg(20180309180233,El,IntToStr(i));
if not ReadInteger(SubObj,'Index',Index,El) then
RaiseMsg(20180309184629,El,IntToStr(i));
if (Index<0) or (Index>=Members.Count) then
RaiseMsg(20180309184718,El,IntToStr(Index)+' out of bounds 0-'+IntToStr(Members.Count));
ChildEl:=TPasElement(Members[Index]);
if ChildEl.Name<>Name then
RaiseMsg(20180309200800,El,'Expected="'+Name+'", but found "'+ChildEl.Name+'"');
// read child declarations
ReadExtRefs(SubObj,ChildEl);
end;
end;
var
Arr: TJSONArray;
Id: Integer;
Data: TJSONData;
SubObj: TJSONObject;
Intf: TInterfaceSection;
Name: string;
begin
{$IFDEF VerbosePJUFiler}
writeln('TPJUReader.ReadExtRefs ',GetObjName(El));
{$ENDIF}
if ReadInteger(Obj,'Id',Id,El) then
AddElReference(Id,El,El);
if ReadArray(Obj,'El',Arr,El) then
begin
if El is TPasDeclarations then
ReadMembers(Arr,TPasDeclarations(El).Declarations)
else if El is TPasClassType then
ReadMembers(Arr,TPasClassType(El).Members)
else if El is TPasRecordType then
ReadMembers(Arr,TPasRecordType(El).Members)
else if El is TPasEnumType then
ReadMembers(Arr,TPasEnumType(El).Values)
else if El is TPasModule then
begin
// a Module has only the Interface as child
if Arr.Count<>1 then
RaiseMsg(20180309180715,El,IntToStr(Arr.Count));
Data:=Arr[0];
if not (Data is TJSONObject) then
RaiseMsg(20180309180745,El);
SubObj:=TJSONObject(Data);
if not ReadString(SubObj,'Name',Name,El) then
RaiseMsg(20180309180749,El);
if Name<>'Interface' then
RaiseMsg(20180309180806,El);
Intf:=TPasModule(El).InterfaceSection;
if Intf=nil then
RaiseMsg(20180309180856,El);
ReadExtRefs(SubObj,Intf);
end
else
RaiseMsg(20180309180610,El);
end;
end;
procedure TPJUReader.ReadUsedUnits(Obj: TJSONObject; Section: TPasSection; procedure TPJUReader.ReadUsedUnits(Obj: TJSONObject; Section: TPasSection;
aContext: TPJUReaderContext); aContext: TPJUReaderContext);
var var
Arr: TJSONArray; Arr: TJSONArray;
i, p: Integer; i, Id: Integer;
Data: TJSONData; Data: TJSONData;
SubObj: TJSONObject; UsesObj, ModuleObj: TJSONObject;
Name, CurName, InFilename, ModuleName: string; Name, InFilename, ModuleName: string;
Use: TPasUsesUnit; Use: TPasUsesUnit;
Prim: TPrimitiveExpr;
Module: TPasModule; Module: TPasModule;
Scope, UsedScope: TPasSectionScope;
begin begin
if not ReadArray(Obj,'Uses',Arr,Section) then exit; if not ReadArray(Obj,'Uses',Arr,Section) then exit;
Scope:=Section.CustomData as TPasSectionScope;
SetLength(Section.UsesClause,Arr.Count); SetLength(Section.UsesClause,Arr.Count);
for i:=0 to length(Section.UsesClause)-1 do for i:=0 to length(Section.UsesClause)-1 do
Section.UsesClause[i]:=nil; Section.UsesClause[i]:=nil;
@ -4328,42 +4448,34 @@ begin
Data:=Arr[i]; Data:=Arr[i];
if not (Data is TJSONObject) then if not (Data is TJSONObject) then
RaiseMsg(20180307103518,Section,GetObjName(Data)); RaiseMsg(20180307103518,Section,GetObjName(Data));
SubObj:=TJSONObject(Data); UsesObj:=TJSONObject(Data);
if not ReadString(SubObj,'Name',Name,Section) then if not ReadString(UsesObj,'Name',Name,Section) then
RaiseMsg(20180307103629,Section); RaiseMsg(20180307103629,Section);
if not IsValidIdent(Name,true,true) then if not IsValidIdent(Name,true,true) then
RaiseMsg(20180307103937,Section,Name); RaiseMsg(20180307103937,Section,Name);
ReadString(SubObj,'In',InFilename,Section); ReadString(UsesObj,'In',InFilename,Section);
ReadString(SubObj,'UnitName',ModuleName,Section); ReadString(UsesObj,'UnitName',ModuleName,Section);
{$IFDEF VerbosePJUFiler}
writeln('TPJUReader.ReadUsedUnits ',i,' Name="',Name,'" In="',InFilename,'" ModuleName="',ModuleName,'"');
{$ENDIF}
Use:=TPasUsesUnit.Create(Name,Section); Use:=TPasUsesUnit.Create(Name,Section);
Section.UsesClause[i]:=Use; Section.UsesClause[i]:=Use;
while Name<>'' do // Use.Expr is not needed
begin
p:=Pos('.',Name);
if p>0 then
begin
CurName:=LeftStr(Name,p-1);
Delete(Name,1,p)
end
else
begin
CurName:=Name;
Name:='';
end;
Prim:=TPrimitiveExpr.Create(Use,pekString,CurName);
if Use.Expr=nil then
Use.Expr:=Prim
else
Use.Expr:=TBinaryExpr.Create(Use,Use.Expr,Prim,eopSubIdent);
end;
if InFilename<>'' then if InFilename<>'' then
Use.InFilename:=TPrimitiveExpr.Create(Use,pekString,InFilename); Use.InFilename:=TPrimitiveExpr.Create(Use,pekString,InFilename);
if ModuleName='' then ModuleName:=Name; if ModuleName='' then ModuleName:=Name;
Module:=Resolver.FindModule(Name,Use.Expr,Use.InFilename); Module:=Resolver.FindModule(Name,Use.Expr,Use.InFilename);
if Module=nil then if Module=nil then
RaiseMsg(20180307231247,Use); RaiseMsg(20180307231247,Use);
Use.Module:=Module;
UsedScope:=Module.InterfaceSection.CustomData as TPasSectionScope;
Scope.UsesScopes.Add(UsedScope);
if ReadInteger(UsesObj,'Id',Id,Use) then
AddElReference(Id,Use,Use);
// Refs // Refs
if ReadObject(UsesObj,'Module',ModuleObj,Use) then
ReadExtRefs(ModuleObj,Module);
end; end;
Resolver.CheckPendingUsedInterface(Section); Resolver.CheckPendingUsedInterface(Section);
if aContext=nil then ; if aContext=nil then ;
@ -6210,7 +6322,7 @@ var
bp: TResolverBuiltInProc; bp: TResolverBuiltInProc;
pbt: TPas2jsBaseType; pbt: TPas2jsBaseType;
begin begin
if not ReadArray(Obj,'System',Arr,ErrorEl) then exit; if not ReadArray(Obj,BuiltInNodeName,Arr,ErrorEl) then exit;
for i:=0 to Arr.Count-1 do for i:=0 to Arr.Count-1 do
begin begin
Data:=Arr[i]; Data:=Arr[i];

View File

@ -45,6 +45,7 @@ type
function OnConverterIsTypeInfoUsed(Sender: TObject; El: TPasElement): boolean; function OnConverterIsTypeInfoUsed(Sender: TObject; El: TPasElement): boolean;
function OnRestConverterIsElementUsed(Sender: TObject; El: TPasElement): boolean; function OnRestConverterIsElementUsed(Sender: TObject; El: TPasElement): boolean;
function OnRestConverterIsTypeInfoUsed(Sender: TObject; El: TPasElement): boolean; function OnRestConverterIsTypeInfoUsed(Sender: TObject; El: TPasElement): boolean;
function OnRestResolverFindUnit(const aUnitName: String): TPasModule;
protected protected
procedure SetUp; override; procedure SetUp; override;
procedure TearDown; override; procedure TearDown; override;
@ -144,6 +145,9 @@ type
procedure TestPC_Proc_UTF8; procedure TestPC_Proc_UTF8;
procedure TestPC_Class; procedure TestPC_Class;
procedure TestPC_Initialization; procedure TestPC_Initialization;
procedure TestPC_UseUnit;
procedure TestPC_UseUnit_Class;
end; end;
function CompareListOfProcScopeRef(Item1, Item2: Pointer): integer; function CompareListOfProcScopeRef(Item1, Item2: Pointer): integer;
@ -203,6 +207,55 @@ begin
Result:=RestAnalyzer.IsTypeInfoUsed(El); Result:=RestAnalyzer.IsTypeInfoUsed(El);
end; end;
function TCustomTestPrecompile.OnRestResolverFindUnit(const aUnitName: String
): TPasModule;
function FindRestUnit(Name: string): TPasModule;
var
i: Integer;
CurEngine: TTestEnginePasResolver;
CurUnitName: String;
begin
for i:=0 to ResolverCount-1 do
begin
CurEngine:=Resolvers[i];
CurUnitName:=ExtractFileUnitName(CurEngine.Filename);
{$IFDEF VerbosePJUFiler}
//writeln('TCustomTestPrecompile.FindRestUnit Checking ',i,'/',ResolverCount,' ',CurEngine.Filename,' ',CurUnitName);
{$ENDIF}
if CompareText(Name,CurUnitName)=0 then
begin
Result:=CurEngine.Module;
if Result<>nil then
begin
{$IFDEF VerbosePJUFiler}
//writeln('TCustomTestPrecompile.FindRestUnit Found parsed module: ',Result.Filename);
{$ENDIF}
exit;
end;
{$IFDEF VerbosePJUFiler}
writeln('TCustomTestPrecompile.FindRestUnit PARSING unit "',CurEngine.Filename,'"');
{$ENDIF}
Fail('not parsed');
end;
end;
end;
var
DefNamespace: String;
begin
if (Pos('.',aUnitName)<1) then
begin
DefNamespace:=GetDefaultNamespace;
if DefNamespace<>'' then
begin
Result:=FindRestUnit(DefNamespace+'.'+aUnitName);
if Result<>nil then exit;
end;
end;
Result:=FindRestUnit(aUnitName);
end;
procedure TCustomTestPrecompile.SetUp; procedure TCustomTestPrecompile.SetUp;
begin begin
inherited SetUp; inherited SetUp;
@ -287,7 +340,7 @@ begin
RestResolver:=TTestEnginePasResolver.Create; RestResolver:=TTestEnginePasResolver.Create;
RestResolver.Filename:=Engine.Filename; RestResolver.Filename:=Engine.Filename;
RestResolver.AddObjFPCBuiltInIdentifiers(btAllJSBaseTypes,bfAllJSBaseProcs); RestResolver.AddObjFPCBuiltInIdentifiers(btAllJSBaseTypes,bfAllJSBaseProcs);
//RestResolver.OnFindUnit:=@OnPasResolverFindUnit; RestResolver.OnFindUnit:=@OnRestResolverFindUnit;
RestParser:=TPasParser.Create(RestScanner,RestFileResolver,RestResolver); RestParser:=TPasParser.Create(RestScanner,RestFileResolver,RestResolver);
RestParser.Options:=po_tcmodules; RestParser.Options:=po_tcmodules;
RestResolver.CurrentParser:=RestParser; RestResolver.CurrentParser:=RestParser;
@ -1666,6 +1719,76 @@ begin
WriteReadUnit; WriteReadUnit;
end; end;
procedure TTestPrecompile.TestPC_UseUnit;
begin
AddModuleWithIntfImplSrc('unit2.pp',
LinesToStr([
'type',
' TColor = longint;',
' TRec = record h: TColor; end;',
' TEnum = (red,green);',
'var',
' c: TColor;',
' r: TRec;',
' e: TEnum;']),
LinesToStr([
'']));
StartUnit(true);
Add([
'interface',
'uses unit2;',
'var',
' i: system.longint;',
' e2: TEnum;',
'implementation',
'initialization',
' c:=1;',
' r.h:=2;',
' e:=red;',
'end.',
'']);
WriteReadUnit;
end;
procedure TTestPrecompile.TestPC_UseUnit_Class;
begin
AddModuleWithIntfImplSrc('unit2.pp',
LinesToStr([
'type',
' TObject = class',
' private',
' FA: longint;',
' public',
' type',
' TEnum = (red,green);',
' public',
' i: longint;',
' e: TEnum;',
' procedure DoIt; virtual; abstract;',
' property A: longint read FA write FA;',
' end;',
'var',
' o: TObject;']),
LinesToStr([
'']));
StartUnit(true);
Add([
'interface',
'uses unit2;',
'var',
' b: TObject;',
'implementation',
'initialization',
' o.DoIt;',
' o.i:=b.A;',
' o.e:=red;',
'end.',
'']);
WriteReadUnit;
end;
Initialization Initialization
RegisterTests([TTestPrecompile]); RegisterTests([TTestPrecompile]);
end. end.

View File

@ -100,10 +100,10 @@ type
function GetResolverCount: integer; function GetResolverCount: integer;
function GetResolvers(Index: integer): TTestEnginePasResolver; function GetResolvers(Index: integer): TTestEnginePasResolver;
function OnPasResolverFindUnit(const aUnitName: String): TPasModule; function OnPasResolverFindUnit(const aUnitName: String): TPasModule;
function FindUnit(const aUnitName: String): TPasModule;
protected protected
procedure SetUp; override; procedure SetUp; override;
function CreateConverter: TPasToJSConverter; virtual; function CreateConverter: TPasToJSConverter; virtual;
function LoadUnit(const aUnitName: String): TPasModule;
procedure InitScanner(aScanner: TPascalScanner); virtual; procedure InitScanner(aScanner: TPascalScanner); virtual;
procedure TearDown; override; procedure TearDown; override;
Procedure Add(Line: string); virtual; Procedure Add(Line: string); virtual;
@ -858,17 +858,17 @@ begin
DefNamespace:=GetDefaultNamespace; DefNamespace:=GetDefaultNamespace;
if DefNamespace<>'' then if DefNamespace<>'' then
begin begin
Result:=FindUnit(DefNamespace+'.'+aUnitName); Result:=LoadUnit(DefNamespace+'.'+aUnitName);
if Result<>nil then exit; if Result<>nil then exit;
end; end;
end; end;
Result:=FindUnit(aUnitName); Result:=LoadUnit(aUnitName);
if Result<>nil then exit; if Result<>nil then exit;
writeln('TTestModule.OnPasResolverFindUnit missing unit "',aUnitName,'"'); writeln('TTestModule.OnPasResolverFindUnit missing unit "',aUnitName,'"');
Fail('can''t find unit "'+aUnitName+'"'); Fail('can''t find unit "'+aUnitName+'"');
end; end;
function TCustomTestModule.FindUnit(const aUnitName: String): TPasModule; function TCustomTestModule.LoadUnit(const aUnitName: String): TPasModule;
var var
i: Integer; i: Integer;
CurEngine: TTestEnginePasResolver; CurEngine: TTestEnginePasResolver;