Repository URL to install this package:
|
Version:
3.0.0 ▾
|
unit passrcutil;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, pscanner, pparser, pastree;
Type
{ TPasSrcAnalysis }
TPasSrcAnalysis = class(TComponent)
private
FFilename : string;
FResolver : TBaseFileResolver;
FScanner : TPascalScanner;
FParser : TPasParser;
FModule : TPasModule;
FContainer : TPasTreeContainer;
FStream: TStream;
procedure SetFileName(AValue: string);
Function ResourceStringCount(Section : TPasSection) : Integer;
Protected
Procedure FreeParser;
Procedure CheckParser;
Procedure Parse;
procedure GetRecordFields(Rec: TPasrecordType; List: TStrings; const APrefix: String = ''); virtual;
procedure GetClassMembers(AClass: TPasClassType; List: TStrings; AVisibilities : TPasMemberVisibilities; const APrefix: String = ''); virtual;
procedure GetEnumValues(Enum: TPasEnumType; List: TStrings; const APrefix: String = ''); virtual;
procedure GetIdentifiers(Section: TPasSection; List: TStrings; Recurse: Boolean);virtual;
procedure GetUses(ASection: TPasSection; List: TStrings);virtual;
Public
Destructor Destroy; override;
Procedure GetInterfaceUnits(List : TStrings);
Procedure GetImplementationUnits(List : TStrings);
Procedure GetUsedUnits(List : TStrings);
Procedure GetInterfaceIdentifiers(List : TStrings; Recurse : Boolean = False);
Procedure GetImplementationIdentifiers(List : TStrings; Recurse : Boolean = False);
Procedure GetAllIdentifiers(List : TStrings; Recurse : Boolean = False);
Function InterfaceHasResourcestrings : Boolean;
Function ImplementationHasResourcestrings : Boolean;
Function HasResourcestrings : Boolean;
Property Stream : TStream Read FStream Write FStream;
Published
Property FileName : string Read FFilename Write SetFileName;
end;
implementation
Type
{ TSrcContainer }
TSrcContainer = Class(TPasTreeContainer)
Public
function CreateElement(AClass: TPTreeElement; const AName: String;
AParent: TPasElement; AVisibility: TPasMemberVisibility;
const ASourceFilename: String; ASourceLinenumber: Integer): TPasElement;overload; override;
function FindElement(const AName: String): TPasElement; override;
end;
{ TSrcContainer }
function TSrcContainer.CreateElement(AClass: TPTreeElement;
const AName: String; AParent: TPasElement; AVisibility: TPasMemberVisibility;
const ASourceFilename: String; ASourceLinenumber: Integer): TPasElement;
begin
Result:=AClass.Create(AName,AParent);
Result.Visibility:=AVisibility;
Result.SourceFilename:=ASourceFileName;
Result.SourceLinenumber:=ASourceLineNumber;
end;
function TSrcContainer.FindElement(const AName: String): TPasElement;
begin
Result:=Nil;
end;
{ TPasSrcAnalysis }
procedure TPasSrcAnalysis.SetFileName(AValue: string);
begin
if FFilename=AValue then Exit;
FFilename:=AValue;
FreeParser;
end;
function TPasSrcAnalysis.ResourceStringCount(Section: TPasSection): Integer;
begin
Result:=0;
If Assigned(Section) and Assigned(Section.ResStrings) then
Result:=Section.ResStrings.Count;;
end;
procedure TPasSrcAnalysis.FreeParser;
begin
FreeAndNil(FParser);
FreeAndNil(FScanner);
FreeAndNil(FContainer);
FreeAndNil(FResolver);
FreeAndNil(FModule);
end;
procedure TPasSrcAnalysis.CheckParser;
Var
D : String;
begin
If (FParser<>Nil) then
exit;
Try
If Assigned(Stream) then
begin
FResolver:=TStreamResolver.Create;
TStreamResolver(Fresolver).AddStream(FileName,Stream);
end
else
FResolver:=TFileResolver.Create;
D:=ExtractFilePath(FileName);
If (D='') then
D:='.';
FResolver.BaseDirectory:=D;
FResolver.AddIncludePath(D);
FScanner:=TPascalScanner.Create(FResolver);
FScanner.OpenFile(FileName);
FContainer:=TSrcContainer.Create;
FParser:=TPasParser.Create(FScanner,FResolver,FContainer);
FScanner.AddDefine('FPC');
except
FreeParser;
Raise;
end;
end;
procedure TPasSrcAnalysis.Parse;
begin
If FModule<>Nil then exit;
CheckParser;
FParser.ParseMain(FModule);
end;
procedure TPasSrcAnalysis.GetRecordFields(Rec: TPasrecordType; List: TStrings;
const APrefix: String = '');
Var
I : Integer;
E : TPasElement;
V : TPasVariant;
begin
For I:=0 to Rec.Members.Count-1 do
begin
E:=TPasElement(Rec.Members[I]);
if E<>Nil then
List.Add(APrefix+E.Name);
end;
If Assigned(Rec.Variants) then
For I:=0 to Rec.Variants.Count-1 do
begin
V:=TPasVariant(Rec.Variants[I]);
if (v<>Nil) and (V.members<>Nil) then
GetRecordFields(V.Members,List,APrefix);
end;
end;
procedure TPasSrcAnalysis.GetClassMembers(AClass: TPasClassType; List: TStrings;
AVisibilities: TPasMemberVisibilities; const APrefix: String);
Var
I : Integer;
E : TPasElement;
V : TPasVariant;
begin
For I:=0 to AClass.Members.Count-1 do
begin
E:=TPasElement(AClass.Members[I]);
if (E<>Nil) and ((AVisibilities=[]) or (E.Visibility in AVisibilities)) then
List.Add(APrefix+E.Name);
end;
end;
destructor TPasSrcAnalysis.Destroy;
begin
FreeParser;
inherited Destroy;
end;
procedure TPasSrcAnalysis.GetUses(ASection : TPasSection; List: TStrings);
Var
I : Integer;
begin
If Assigned(ASection) and Assigned(ASection.UsesList) then
For I:=0 to ASection.UsesList.Count-1 do
List.Add(TPasElement(ASection.UsesList[i]).Name);
end;
procedure TPasSrcAnalysis.GetInterfaceUnits(List: TStrings);
begin
Parse;
GetUses(Fmodule.InterfaceSection,List);
end;
procedure TPasSrcAnalysis.GetImplementationUnits(List: TStrings);
begin
Parse;
GetUses(Fmodule.ImplementationSection,List);
end;
procedure TPasSrcAnalysis.GetUsedUnits(List: TStrings);
begin
Parse;
GetUses(Fmodule.InterfaceSection,List);
GetUses(Fmodule.ImplementationSection,List);
end;
procedure TPasSrcAnalysis.GetEnumValues(Enum : TPasEnumType;List : TStrings; Const APrefix : String = '');
Var
I : Integer;
E : TPasElement;
begin
For I:=0 to Enum.Values.Count-1 do
begin
E:=TPasElement(Enum.Values[I]);
If (E<>Nil) then
List.Add(APrefix+E.Name);
end;
end;
procedure TPasSrcAnalysis.GetIdentifiers(Section : TPasSection; List: TStrings; Recurse : Boolean);
Var
I : Integer;
E : TPasElement;
begin
if not (Assigned(Section) and Assigned(Section.Declarations)) then
Exit;
For I:=0 to Section.Declarations.Count-1 do
begin
E:=TPasElement(Section.Declarations[I]);
If (E.Name<>'') then
List.Add(E.Name);
if Recurse then
begin
If E is TPasEnumType then
GetEnumValues(TPasEnumType(E),List,E.Name+'.')
else if E is TPasRecordType then
GetRecordFields(TPasRecordType(E),List,E.Name+'.')
else if E is TPasClassType then
GetClassMembers(TPasClassType(E),List,[],E.Name+'.')
end;
end;
end;
procedure TPasSrcAnalysis.GetInterfaceIdentifiers(List: TStrings; Recurse : Boolean = False);
begin
Parse;
GetIdentifiers(Fmodule.InterfaceSection,List,Recurse);
end;
procedure TPasSrcAnalysis.GetImplementationIdentifiers(List: TStrings;
Recurse: Boolean);
begin
Parse;
GetIdentifiers(Fmodule.ImplementationSection,List,Recurse);
end;
procedure TPasSrcAnalysis.GetAllIdentifiers(List: TStrings; Recurse: Boolean);
begin
Parse;
GetIdentifiers(Fmodule.InterfaceSection,List,Recurse);
GetIdentifiers(Fmodule.ImplementationSection,List,Recurse);
end;
function TPasSrcAnalysis.InterfaceHasResourcestrings: Boolean;
begin
Parse;
Result:=ResourceStringCount(Fmodule.InterfaceSection)>0;
end;
function TPasSrcAnalysis.ImplementationHasResourcestrings: Boolean;
begin
Parse;
Result:=ResourceStringCount(Fmodule.ImplementationSection)>0;
end;
function TPasSrcAnalysis.HasResourcestrings: Boolean;
begin
Parse;
Result:=(ResourceStringCount(Fmodule.InterfaceSection)>0)
or (ResourceStringCount(Fmodule.ImplementationSection)>0);
end;
end.