📄 ubaseidents.pas
字号:
procedure ReservedWord(const Word: String); virtual;
//Will be called for all texts of identifiers.
procedure IdentifierText(const Text: String); virtual;
//Will be called for all names of identifier-type identifiers.
procedure TypeIdentifierText(Ident: TIdentifier); virtual;
//Will be called for a text of a type identifier.
procedure TypeText(const TypeStr: String); virtual;
//Will be called for all expressions.
procedure ExprText(const ExprStr: String); virtual;
//Will be called for texts.
procedure Text(const Text: String); virtual;
//Will be called for read- and write-attributes of properties.
procedure PropertyReadWrite(const ReadWrite: String; Prop: TProperty);
virtual;
//Will be called for implements-attribute of properties.
procedure PropertyImplements(Prop: TProperty); virtual;
//Will be called for a reference on a method of an implemented interface.
procedure InterfaceMethod(const Name: String; Method: TIdentifier);
virtual;
//Will be called for a reference on a method.
procedure MethodName(const Name: String; MethodOf: TRecordType); virtual;
property SourceIdent: TIdentifier read FSourceIdent;
end;
{ * * * *** * * * *** TIdentifier *** * * * *** * * * }
TIdentType = class; //the class for identifier type-identifiers
{A call back-procedure for ~[link TIdentifier.ForEachIdentType];
will be called for all ~[linkClass TIdentType]s.
~param Ident the TIdentType-identifier
~param Parent the identifier that uses it directly
~param Data a free usable pointer for the call back-procedure }
TForEachIdentTypeProc = procedure (Ident: TIdentType; Parent: TIdentifier;
Data: TIdentifier) of object;
//a reference to a class of identifiers
TIdentifierClass = class of TIdentifier;
{The abstract base class of all identifiers. Every identifier is represented
by an instance of a subclass of this class. Every defined identifier
inherits its name from this class, internal (anonymous) identifiers
(like used for types) don't have a name. The position of the declaration
will be saved, and if the identifier has a forward declaration (for
functions, classes of the class-model and interfaces) this position will be
saved, too, else the position will be used as position of the forward
declaration. The scope of the declaration will also be saved.~[br]
All identifiers have an index, in case there are multiple identifiers with
the same name. This can only happen with overloaded functions, but is also
used with any kind of record-like types. A list of all identifiers
(currently only functions) that use this identifier is also contained.~[br]
All identifiers can be ~[link clone]d, so you get a new instance of the same
class with the same values (except the list of using identifiers and the
index of the name). A string with the description (most like the declaration
in the pascal file) can be obtained by calling the function ~[link
GetDescriptionString]. If an identifier is another one or if it is included
in it (like the anonymous identifier of the type of a variable is included
in the identifier of the variable) can be tested with ~[link RecursiveIsIn].
For each instance of the class ~[linkClass TIdentType] a call back-function
can be called by using the method ~[link ForEachIdentType]. ~[link
GenerateCrossReference] has to be called to update the list of all using
identifiers, this means all functions add themselves to the list of using
identifiers of all identifiers they are using.
~[diagram /class /members /showfile=0 /layout=post /size=8 /margin=5
TIdentifier.tree]}
TIdentifier = class
private
//name of the identifier
FName: String;
//the file the identifier is declared in
FInFile: TPascalFile;
//the containing type, i.e. the record-like type this identifier is a
//member of; may also be used for nested types and constants (Delphi 8+)
FMemberOf: TRecordType;
//position of declaration
FPosition: TPosition;
//first declaration of the identifier
FForwardDefPos: TPosition;
//scope of the identifier
FScope: TScope;
//portability-issues of the identifier
FPortability: TIdentPortabilities;
//portability-issues of the identifier and all containing it
FSummarizedPortability: TIdentPortabilities;
//the file the identifier is declared in; if it is defined in an included
//file, this will be the included file
FEffectiveFile: TPascalFile;
//the position of the declaration of the identifier; if it is defined in an
//included file, this will be the position inside the included file
FEffectivePosition: TPosition;
//the file the identifier is first declared in; if it is defined in an
//included file, this will be the included file
FEffectiveForwardFile: TPascalFile;
//the position of the first declaration of the identifier; if it is defined
//in an included file, this will be the position inside the included file
FEffectiveForwardPosition: TPosition;
//number of the identifier with this name, if there is more than one
//identifier with the same name in the same scope/name space (or
//documentation name space (i.e. all record-like type in the
//HTML-generator)), this index will be incremented for each identifier
FInternalNameIndex: Cardinal;
//a list of all identifiers that use this one
FUsedByIdents: TIdentifierList;
protected
//Copies all data of this identifier to the Clone.
procedure CloneTo(Clone: TIdentifier); virtual;
//Returns the list containing this identifier.
function GetParentList: TIdentifierList; virtual;
public
//Creates a new instance of an identifier.
constructor Create; virtual;
//Destroys the list of using identifiers.
destructor Destroy; override;
//Gets the version the identifier will save its data in by ~[link Save].
class function GetVersion: TIdentClassVersion; virtual;
//Checks if the identifier can read data of the version by ~[link Load].
class function CheckVersion(Version: TIdentClassVersion): Boolean; virtual;
//Creates a new identifier and copies all values to it.
function Clone: TIdentifier;
//Calls Proc with each instance of TIdentType.
procedure ForEachIdentType(Proc: TForEachIdentTypeProc; Parent: TIdentifier;
Data: TIdentifier = nil); virtual;
//Adds the given set to its own and all contained identifiers.
procedure AddPortabilityIssues(Portability: TIdentPortabilities); virtual;
//Tests if it is or contains Ident.
function RecursiveIsIn(Ident: TIdentifier): Boolean; virtual;
{Gets a description of the identifier, mostly like it has been declared in
the pascal data.
~param TextFormat an object as a set of call back-functions to format text
~param SourceIdent the identifier for which the whole description should be
generated
~result the description of the identifier formatted by TextFormat }
function GetDescriptionString(TextFormat: TTextFormat;
SourceIdent: TIdentifier = nil): String;
virtual; abstract;
{Gets the declaration of the identifier in an internal representation.
~param Assembly an object with a set of call back-functions to save the
declaration }
procedure GetDeclaration(Assembly: TDeclarationAssembler); virtual;
abstract;
//Generates a cross reference, by adding each identifier to each
//identifier's ~[link UsedByIdents]-list it's using.
function GenerateCrossReference: TIdentifier; virtual;
//Adds itself and all owned identifiers to the list.
procedure AddToList(List: TIdentifierList); virtual;
//Saves the identifier to the stream.
procedure Save(Stream: TIdentStream); virtual;
//Loads the identifier from the stream.
procedure Load(Stream: TIdentStream; Version: TIdentClassVersion); virtual;
//Compares this identifier with the other one.
function CompareWith(Ident: TIdentifier; const MsgPrefix: String;
Messages: TStrings): Boolean; virtual;
property Name: String read FName write FName;
property InFile: TPascalFile read FInFile write FInFile;
property MemberOf: TRecordType read FMemberOf write FMemberOf;
property Position: TPosition read FPosition write FPosition;
property ForwardDefPos: TPosition read FForwardDefPos write FForwardDefPos;
property Scope: TScope read FScope write FScope;
property Portability: TIdentPortabilities read FPortability
write FPortability;
property SummarizedPortability: TIdentPortabilities
read FSummarizedPortability
write FSummarizedPortability;
property EffectiveFile: TPascalFile read FEffectiveFile
write FEffectiveFile;
property EffectivePosition: TPosition read FEffectivePosition
write FEffectivePosition;
property EffectiveForwardFile: TPascalFile read FEffectiveForwardFile
write FEffectiveForwardFile;
property EffectiveForwardPosition: TPosition
read FEffectiveForwardPosition write FEffectiveForwardPosition;
property InternalNameIndex: Cardinal read FInternalNameIndex
write FInternalNameIndex;
property UsedByIdents: TIdentifierList read FUsedByIdents
write FUsedByIdents;
property ParentList: TIdentifierList read GetParentList;
end;
{ * * * *** * * * *** TType *** * * * *** * * * }
{The abstract base class of all type identifiers. Besides having an own base
class for all type identifiers is a good idea, this class introduces a field
to save if the type is declared as a strict, own type, what means it is not
identical with the type it is defined as. It also introduces a method to
check if two types are equal when comparing parameters, especially of
overloaded functions. }
TType = class(TIdentifier)
private
//if it is a strict type
FStrictOwnType: Boolean;
protected
//Copies all data of this identifier to the Clone.
procedure CloneTo(Clone: TIdentifier); override;
public
//Gets a description of the identifier, mostly like it has been declared in
//the pascal data.
function GetDescriptionString(TextFormat: TTextFormat;
SourceIdent: TIdentifier = nil): String;
override;
//Gets the declaration of the identifier in an internal representation.
procedure GetDeclaration(Assembly: TDeclarationAssembler); override;
{Tests if this identifier is equal to Other as regards content. This is
used to compare parameters to decide which forward declaration of
overloaded functions should be used for an implementing function.
~param Other the type to compare with the type represented by this object
~result if the both types are equal }
function ParamEqualTo(Other: TType): Boolean; virtual; abstract;
//Saves the identifier to the stream.
procedure Save(Stream: TIdentStream); override;
//Loads the identifier from the stream.
procedure Load(Stream: TIdentStream; Version: TIdentClassVersion);
override;
//Compares this identifier with the other one.
function CompareWith(Ident: TIdentifier; const MsgPrefix: String;
Messages: TStrings): Boolean; override;
property StrictOwnType: Boolean read FStrictOwnType write FStrictOwnType;
end;
{ * * * *** * * * *** TIdentType *** * * * *** * * * }
{The class for types defined by an identifier, it holds the name of the
identifier and can hold the link to it. Consider the following example:
~[sample
type MyType = 4..10;
procedure MyProc(One: MyType; Two: Integer);]
When parsing that pascal data a type-identifier will be created of the class
~[linkClass TSubRangeType] and the name MyType. After that the procedure
~[code MyProc] will be parsed and for it two parameters will be created:
~[code One] and ~[code Two]. Each of them has a type, and an identifier for
it will be assigned to them. They are not a type on its own, rather a name
of a somewhere else defined type. For both types an object of this class,
~[code TIdentType], will be created, one with the text ~[code MyType] the
other with ~[code Integer]. At a later stage of the parsing for each object
of the class ~[code TIdentType] the type for the text will be searched and a
reference will be set on it. So the type of ~[code One] will get a reference
on ~[code MyType], but the type of ~[code Two] will (as long as the unit
System hasn't be parsed) get no reference, hence it can only use its text. }
TIdentType = class(TType)
private
//the text of the type identifier
FDefIdent: String;
//the identifier of the type (if found)
FTheType: TType;
protected
//Copies all data of this identifier to the Clone.
procedure CloneTo(Clone: TIdentifier); override;
public
//Returns referenced type.
function GetFinalType: TType;
//Calls Proc with each instance of TIdentType, this means it is called.
procedure ForEachIdentType(Proc: TForEachIdentTypeProc; Parent: TIdentifier;
Data: TIdentifier = nil); override;
//Gets a description of the identifier, mostly like it has been declared in
//the pascal data.
function GetDescriptionString(TextFormat: TTextFormat;
SourceIdent: TIdentifier = nil): String;
override;
//Gets the declaration of the identifier in an internal representation.
procedure GetDeclaration(Assembly: TDeclarationAssembler); override;
//Tests if this identifier is equal to Other as regards content.
function ParamEqualTo(Other: TType): Boolean; override;
//Saves the identifier to the stream.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -