mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 21:49:18 +02:00
* Fix parsing uses unit in filename, added library parsing and exports sections
git-svn-id: trunk@21915 -
This commit is contained in:
parent
07ebc51b6c
commit
7a1d4dfe72
@ -249,7 +249,7 @@ type
|
|||||||
function ElementTypeName: string; override;
|
function ElementTypeName: string; override;
|
||||||
public
|
public
|
||||||
Declarations, ResStrings, Types, Consts, Classes,
|
Declarations, ResStrings, Types, Consts, Classes,
|
||||||
Functions, Variables, Properties: TFPList;
|
Functions, Variables, Properties, ExportSymbols: TFPList;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TPasSection }
|
{ TPasSection }
|
||||||
@ -276,6 +276,9 @@ type
|
|||||||
TProgramSection = class(TImplementationSection)
|
TProgramSection = class(TImplementationSection)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TLibrarySection = class(TImplementationSection)
|
||||||
|
end;
|
||||||
|
|
||||||
TInitializationSection = class;
|
TInitializationSection = class;
|
||||||
TFinalizationSection = class;
|
TFinalizationSection = class;
|
||||||
|
|
||||||
@ -308,7 +311,18 @@ type
|
|||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
function ElementTypeName: string; override;
|
function ElementTypeName: string; override;
|
||||||
Public
|
Public
|
||||||
ProgramSection: TInterfaceSection;
|
ProgramSection: TProgramSection;
|
||||||
|
InputFile,OutPutFile : String;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TPasLibrary }
|
||||||
|
|
||||||
|
TPasLibrary = class(TPasModule)
|
||||||
|
Public
|
||||||
|
destructor Destroy; override;
|
||||||
|
function ElementTypeName: string; override;
|
||||||
|
Public
|
||||||
|
LibrarySection: TLibrarySection;
|
||||||
InputFile,OutPutFile : String;
|
InputFile,OutPutFile : String;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -567,13 +581,24 @@ type
|
|||||||
ResultEl: TPasResultElement;
|
ResultEl: TPasResultElement;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TPasUnresolvedTypeRef = class(TPasType)
|
TPasUnresolvedSymbolRef = class(TPasType)
|
||||||
|
end;
|
||||||
|
|
||||||
|
TPasUnresolvedTypeRef = class(TPasUnresolvedSymbolRef)
|
||||||
public
|
public
|
||||||
// Typerefs cannot be parented! -> AParent _must_ be NIL
|
// Typerefs cannot be parented! -> AParent _must_ be NIL
|
||||||
constructor Create(const AName: string; AParent: TPasElement); override;
|
constructor Create(const AName: string; AParent: TPasElement); override;
|
||||||
function ElementTypeName: string; override;
|
function ElementTypeName: string; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TPasUnresolvedUnitRef }
|
||||||
|
|
||||||
|
TPasUnresolvedUnitRef = Class(TPasUnresolvedSymbolRef)
|
||||||
|
function ElementTypeName: string; override;
|
||||||
|
Public
|
||||||
|
FileName : string;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TPasStringType }
|
{ TPasStringType }
|
||||||
|
|
||||||
TPasStringType = class(TPasUnresolvedTypeRef)
|
TPasStringType = class(TPasUnresolvedTypeRef)
|
||||||
@ -605,6 +630,16 @@ type
|
|||||||
Expr: TPasExpr;
|
Expr: TPasExpr;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TPasExportSymbol }
|
||||||
|
|
||||||
|
TPasExportSymbol = class(TPasElement)
|
||||||
|
ExportName : TPasExpr;
|
||||||
|
Exportindex : TPasExpr;
|
||||||
|
Destructor Destroy; override;
|
||||||
|
function ElementTypeName: string; override;
|
||||||
|
function GetDeclaration(full : boolean) : string; override;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TPasConst }
|
{ TPasConst }
|
||||||
|
|
||||||
TPasConst = class(TPasVariable)
|
TPasConst = class(TPasVariable)
|
||||||
@ -1078,6 +1113,50 @@ implementation
|
|||||||
|
|
||||||
uses SysUtils;
|
uses SysUtils;
|
||||||
|
|
||||||
|
{ TPasExportSymbol }
|
||||||
|
|
||||||
|
destructor TPasExportSymbol.Destroy;
|
||||||
|
begin
|
||||||
|
FreeAndNil(ExportName);
|
||||||
|
FreeAndNil(ExportIndex);
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPasExportSymbol.ElementTypeName: string;
|
||||||
|
begin
|
||||||
|
Result:='Export'
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPasExportSymbol.GetDeclaration(full: boolean): string;
|
||||||
|
begin
|
||||||
|
Result:=Name;
|
||||||
|
if (ExportName<>Nil) then
|
||||||
|
Result:=Result+' name '+ExportName.GetDeclaration(Full)
|
||||||
|
else if (ExportIndex<>Nil) then
|
||||||
|
Result:=Result+' index '+ExportIndex.GetDeclaration(Full);
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TPasUnresolvedUnitRef }
|
||||||
|
|
||||||
|
function TPasUnresolvedUnitRef.ElementTypeName: string;
|
||||||
|
begin
|
||||||
|
Result:=SPasTreeUnit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TPasLibrary }
|
||||||
|
|
||||||
|
destructor TPasLibrary.Destroy;
|
||||||
|
begin
|
||||||
|
FreeAndNil(LibrarySection);
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPasLibrary.ElementTypeName: string;
|
||||||
|
begin
|
||||||
|
Result:=inherited ElementTypeName;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TPasProgram }
|
{ TPasProgram }
|
||||||
|
|
||||||
destructor TPasProgram.Destroy;
|
destructor TPasProgram.Destroy;
|
||||||
@ -1291,12 +1370,14 @@ begin
|
|||||||
Functions := TFPList.Create;
|
Functions := TFPList.Create;
|
||||||
Variables := TFPList.Create;
|
Variables := TFPList.Create;
|
||||||
Properties := TFPList.Create;
|
Properties := TFPList.Create;
|
||||||
|
ExportSymbols := TFPList.Create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TPasDeclarations.Destroy;
|
destructor TPasDeclarations.Destroy;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
|
ExportSymbols.Free;
|
||||||
Variables.Free;
|
Variables.Free;
|
||||||
Functions.Free;
|
Functions.Free;
|
||||||
Classes.Free;
|
Classes.Free;
|
||||||
|
@ -200,6 +200,7 @@ type
|
|||||||
Function ParseClassDecl(Parent: TPasElement; const AClassName: String; AObjKind: TPasObjKind; PackMode : TPackMode= pmNone): TPasType;
|
Function ParseClassDecl(Parent: TPasElement; const AClassName: String; AObjKind: TPasObjKind; PackMode : TPackMode= pmNone): TPasType;
|
||||||
Function ParseProperty(Parent : TPasElement; Const AName : String; AVisibility : TPasMemberVisibility; IsClass : Boolean) : TPasProperty;
|
Function ParseProperty(Parent : TPasElement; Const AName : String; AVisibility : TPasMemberVisibility; IsClass : Boolean) : TPasProperty;
|
||||||
function ParseRangeType(AParent: TPasElement; Const TypeName: String; Full : Boolean = True): TPasRangeType;
|
function ParseRangeType(AParent: TPasElement; Const TypeName: String; Full : Boolean = True): TPasRangeType;
|
||||||
|
procedure ParseExportDecl(Parent: TPasElement; List: TFPList);
|
||||||
// Constant declarations
|
// Constant declarations
|
||||||
function ParseConstDecl(Parent: TPasElement): TPasConst;
|
function ParseConstDecl(Parent: TPasElement): TPasConst;
|
||||||
function ParseResourcestringDecl(Parent: TPasElement): TPasResString;
|
function ParseResourcestringDecl(Parent: TPasElement): TPasResString;
|
||||||
@ -210,6 +211,7 @@ type
|
|||||||
procedure ParseMain(var Module: TPasModule);
|
procedure ParseMain(var Module: TPasModule);
|
||||||
procedure ParseUnit(var Module: TPasModule);
|
procedure ParseUnit(var Module: TPasModule);
|
||||||
procedure ParseProgram(var Module: TPasModule; SkipHeader : Boolean = False);
|
procedure ParseProgram(var Module: TPasModule; SkipHeader : Boolean = False);
|
||||||
|
procedure ParseLibrary(var Module: TPasModule);
|
||||||
procedure ParseUsesList(ASection: TPasSection);
|
procedure ParseUsesList(ASection: TPasSection);
|
||||||
procedure ParseInterface;
|
procedure ParseInterface;
|
||||||
procedure ParseImplementation;
|
procedure ParseImplementation;
|
||||||
@ -252,7 +254,8 @@ const
|
|||||||
WhitespaceTokensToIgnore = [tkWhitespace, tkComment, tkLineEnding, tkTab];
|
WhitespaceTokensToIgnore = [tkWhitespace, tkComment, tkLineEnding, tkTab];
|
||||||
|
|
||||||
type
|
type
|
||||||
TDeclType = (declNone, declConst, declResourcestring, declType, declVar, declThreadvar, declProperty);
|
TDeclType = (declNone, declConst, declResourcestring, declType,
|
||||||
|
declVar, declThreadvar, declProperty, declExports);
|
||||||
|
|
||||||
Function IsHintToken(T : String; Out AHint : TPasMemberHint) : boolean;
|
Function IsHintToken(T : String; Out AHint : TPasMemberHint) : boolean;
|
||||||
|
|
||||||
@ -1634,6 +1637,8 @@ begin
|
|||||||
ParseUnit(Module);
|
ParseUnit(Module);
|
||||||
tkProgram:
|
tkProgram:
|
||||||
ParseProgram(Module);
|
ParseProgram(Module);
|
||||||
|
tkLibrary:
|
||||||
|
ParseLibrary(Module);
|
||||||
else
|
else
|
||||||
ungettoken;
|
ungettoken;
|
||||||
ParseProgram(Module,True);
|
ParseProgram(Module,True);
|
||||||
@ -1706,7 +1711,34 @@ begin
|
|||||||
ParseExc(Format(SParserExpectTokenError,[';']));
|
ParseExc(Format(SParserExpectTokenError,[';']));
|
||||||
end;
|
end;
|
||||||
Section := TProgramSection(CreateElement(TProgramSection, '', CurModule));
|
Section := TProgramSection(CreateElement(TProgramSection, '', CurModule));
|
||||||
PP.ImplementationSection := Section;
|
PP.ProgramSection := Section;
|
||||||
|
ParseDeclarations(Section);
|
||||||
|
finally
|
||||||
|
FCurModule:=nil;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TPasParser.ParseLibrary(var Module: TPasModule);
|
||||||
|
Var
|
||||||
|
PP : TPasLibrary;
|
||||||
|
Section : TLibrarySection;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Module := nil;
|
||||||
|
PP:=TPasLibrary(CreateElement(TPasLibrary, ExpectIdentifier, Engine.Package));
|
||||||
|
Module :=PP;
|
||||||
|
FCurModule:=Module;
|
||||||
|
try
|
||||||
|
if Assigned(Engine.Package) then
|
||||||
|
begin
|
||||||
|
Module.PackageName := Engine.Package.Name;
|
||||||
|
Engine.Package.Modules.Add(Module);
|
||||||
|
end;
|
||||||
|
NextToken;
|
||||||
|
if (CurToken<>tkSemicolon) then
|
||||||
|
ParseExc(Format(SParserExpectTokenError,[';']));
|
||||||
|
Section := TLibrarySection(CreateElement(TLibrarySection, '', CurModule));
|
||||||
|
PP.LibrarySection := Section;
|
||||||
ParseDeclarations(Section);
|
ParseDeclarations(Section);
|
||||||
finally
|
finally
|
||||||
FCurModule:=nil;
|
FCurModule:=nil;
|
||||||
@ -1822,6 +1854,7 @@ var
|
|||||||
List: TFPList;
|
List: TFPList;
|
||||||
i,j: Integer;
|
i,j: Integer;
|
||||||
VarEl: TPasVariable;
|
VarEl: TPasVariable;
|
||||||
|
ExpEl: TPasExportSymbol;
|
||||||
PropEl : TPasProperty;
|
PropEl : TPasProperty;
|
||||||
TypeName: String;
|
TypeName: String;
|
||||||
PT : TProcType;
|
PT : TProcType;
|
||||||
@ -1872,6 +1905,8 @@ begin
|
|||||||
ParseExc(SParserSyntaxError);
|
ParseExc(SParserSyntaxError);
|
||||||
tkConst:
|
tkConst:
|
||||||
CurBlock := declConst;
|
CurBlock := declConst;
|
||||||
|
tkexports:
|
||||||
|
CurBlock := declExports;
|
||||||
tkResourcestring:
|
tkResourcestring:
|
||||||
CurBlock := declResourcestring;
|
CurBlock := declResourcestring;
|
||||||
tkType:
|
tkType:
|
||||||
@ -1947,6 +1982,27 @@ begin
|
|||||||
Declarations.Types.Add(TypeEl);
|
Declarations.Types.Add(TypeEl);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
declExports:
|
||||||
|
begin
|
||||||
|
List := TFPList.Create;
|
||||||
|
try
|
||||||
|
try
|
||||||
|
ParseExportDecl(Declarations, List);
|
||||||
|
except
|
||||||
|
for i := 0 to List.Count - 1 do
|
||||||
|
TPasExportSymbol(List[i]).Release;
|
||||||
|
raise;
|
||||||
|
end;
|
||||||
|
for i := 0 to List.Count - 1 do
|
||||||
|
begin
|
||||||
|
ExpEl := TPasExportSymbol(List[i]);
|
||||||
|
Declarations.Declarations.Add(ExpEl);
|
||||||
|
Declarations.ExportSymbols.Add(ExpEl);
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
List.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
declVar, declThreadVar:
|
declVar, declThreadVar:
|
||||||
begin
|
begin
|
||||||
List := TFPList.Create;
|
List := TFPList.Create;
|
||||||
@ -2034,7 +2090,7 @@ begin
|
|||||||
if Assigned(result) then
|
if Assigned(result) then
|
||||||
result.AddRef
|
result.AddRef
|
||||||
else
|
else
|
||||||
Result := TPasType(CreateElement(TPasUnresolvedTypeRef, AUnitName,
|
Result := TPasType(CreateElement(TPasUnresolvedUnitRef, AUnitName,
|
||||||
ASection));
|
ASection));
|
||||||
ASection.UsesList.Add(Result);
|
ASection.UsesList.Add(Result);
|
||||||
end;
|
end;
|
||||||
@ -2043,28 +2099,25 @@ var
|
|||||||
AUnitName: String;
|
AUnitName: String;
|
||||||
Element: TPasElement;
|
Element: TPasElement;
|
||||||
begin
|
begin
|
||||||
If not (Asection is TImplementationSection) Then // interface,program,library,package
|
If not (Asection.ClassType=TImplementationSection) Then // interface,program,library,package
|
||||||
Element:=CheckUnit('System'); // system always implicitely first.
|
Element:=CheckUnit('System'); // system always implicitely first.
|
||||||
while True do
|
Repeat
|
||||||
begin
|
|
||||||
AUnitName := ExpectIdentifier;
|
AUnitName := ExpectIdentifier;
|
||||||
Element :=CheckUnit(AUnitName);
|
Element :=CheckUnit(AUnitName);
|
||||||
|
|
||||||
NextToken;
|
NextToken;
|
||||||
|
if (CurToken=tkin) then
|
||||||
if CurToken = tkin then begin
|
begin
|
||||||
// todo: store unit's file name somewhere
|
ExpectToken(tkString);
|
||||||
NextToken; // skip in
|
if (Element is TPasModule) and (TPasmodule(Element).filename='') then
|
||||||
ExpectToken(tkString); // skip unit's real file name
|
TPasModule(Element).FileName:=curtokenstring
|
||||||
if (Element is TPasModule) and (TPasmodule(Element).filename<>'') then
|
else if (Element is TPasUnresolvedUnitRef) then
|
||||||
TPasModule(Element).FileName:=curtokenstring;
|
TPasUnresolvedUnitRef(Element).FileName:=curtokenstring;
|
||||||
|
NextToken;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if CurToken = tkSemicolon then
|
if Not (CurToken in [tkComma,tkSemicolon]) then
|
||||||
break
|
|
||||||
else if CurToken <> tkComma then
|
|
||||||
ParseExc(SParserExpectedCommaSemicolon);
|
ParseExc(SParserExpectedCommaSemicolon);
|
||||||
end;
|
Until (CurToken=tkSemicolon);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Starts after the variable name
|
// Starts after the variable name
|
||||||
@ -2159,6 +2212,30 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Starts after Exports, on first identifier.
|
||||||
|
procedure TPasParser.ParseExportDecl(Parent: TPasElement; List: TFPList);
|
||||||
|
Var
|
||||||
|
E : TPasExportSymbol;
|
||||||
|
begin
|
||||||
|
Repeat
|
||||||
|
E:=TPasExportSymbol(CreateElement(TPasExportSymbol,CurtokenString,Parent));
|
||||||
|
List.Add(E);
|
||||||
|
NextToken;
|
||||||
|
if CurTokenIsIdentifier('INDEX') then
|
||||||
|
begin
|
||||||
|
NextToken;
|
||||||
|
E.Exportindex:=DoParseExpression(E,Nil)
|
||||||
|
end
|
||||||
|
else if CurTokenIsIdentifier('NAME') then
|
||||||
|
begin
|
||||||
|
NextToken;
|
||||||
|
E.ExportName:=DoParseExpression(E,Nil)
|
||||||
|
end;
|
||||||
|
if not (CurToken in [tkComma,tkSemicolon]) then
|
||||||
|
ParseExc(SParserExpectedCommaSemicolon);
|
||||||
|
until (CurToken=tkSemicolon);
|
||||||
|
end;
|
||||||
|
|
||||||
Function TPasParser.ParseSpecializeType(Parent : TPasElement; Const TypeName : String) : TPasClassType;
|
Function TPasParser.ParseSpecializeType(Parent : TPasElement; Const TypeName : String) : TPasClassType;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
Loading…
Reference in New Issue
Block a user