📄 uicdeclarationassembler.pas
字号:
if (State = sString) and (Token[1] in ['#', '^']) and
Parser.GetToken(Token) then //and it is available?
Text(Token); //add character number or the escaped control character
end; //else identifier or reserved word
end; //while Parser.GetIdentWithPointsToken
finally
Parser.Free; //free tokenizer
end;
end;
{Will be called for all simple texts without identifiers (i.e. spaces and
special characters like colons and equal signs).
~param Text the text }
procedure TICDeclarationAssembler.Text(const Text: String);
begin
FCacheText := FCacheText + Text;
end;
{Will be called for texts of a member used as read or write-attribute of a
property. The member is underlaid with a link to their declaration if
possible.
~param ReadWrite the text of the member as used by the read- or write-attribute
of a property
~param Prop the property whose attribute should be added }
procedure TICDeclarationAssembler.PropertyReadWrite(const ReadWrite: String;
Prop: TProperty);
var simple :String; //simplified version of the name
dot :Integer; //position of point in string
IdentName :String; //name of the identifier
Ident :TIdentifier; //the identifier
begin
Assert(Assigned(SourceIdent));
Assert(Assigned(SourceIdent.InFile));
Assert(ReadWrite <> '');
if Assigned(Prop) and Assigned(Prop.MemberOf) then
begin
//delete all whitespace for simpler parsing
simple := DeleteAllWhiteSpaces(ReadWrite);
dot := Pos('.', simple); //get first identifier
if dot <> 0 then
begin
IdentName := Copy(simple, 1, dot - 1); //extract first identifier
Delete(simple, 1, dot - 1); //the remnant (including dot)
end
else
begin
IdentName := simple; //only a simple identifier
simple := '';
end;
//search the identifier in the class
Ident := Prop.MemberOf.FindMember(IdentName, SourceIdent.InFile, True);
if Assigned(Ident) then //identifier found?
CreateLink(Ident) //generate a link on it
else
IdentifierText(IdentName); //just add the text
if simple <> '' then //some field inside a record?
IdentifierText(simple); //add it
end
else
IdentifierText(ReadWrite); //just add the text
end;
{Will be called for implements-attribute of properties. The interfaces should
be added underlaid with a link to its declaration if possible.
~param Prop the property whose implemented interface should be added }
procedure TICDeclarationAssembler.PropertyImplements(Prop: TProperty);
var Source :String; //list of redirected interfaces
List :TIdentifierList; //list of implemented interfaces
First :Boolean; //first interface to be read?
i :Integer; //general index
One, LC :String; //each implemented interface
Interf :TIdentifier; //the interface
begin
Assert(Assigned(SourceIdent));
Assert(Assigned(SourceIdent.InFile));
Source := Prop.ImplementsInterfaces; //get definition of the attribute
List := Prop.MemberOf.Implementing; //get the implemented interfaces
{$IFOPT C+}
for i := 0 to List.Count - 1 do
Assert(List[i] is TIdentType);
{$ENDIF}
First := True; //the next will be the first
while Source <> '' do //for each interface
begin
if First then //first interface?
First := False //next won't be
else
Text(', '); //add separator
i := Pos(', ', Source);
if i = 0 then //extract it
begin
One := Source;
Source := '';
end
else
begin
One := Copy(Source, 1, i - 1);
Delete(Source, 1, i + 1);
end;
LC := LowerCase(One); //in lower case
//search the interface manually
Interf := FGenerator.FindIdentifier(One, Prop.InFile,
Prop.MemberOf.Position);
if Assigned(Interf) and //identifier found and valid kind?
((Interf is TRecordType) or (Interf is TIdentType)) then
begin
CreateLink(Interf, Pos('.', One) <> 0); //add link to it
if Assigned(FOnUnknownInterface) then //handler for it defined?
begin
//check if it is an implemented interface
if Interf is TIdentType then
Interf := TIdentType(Interf).GetFinalType;
if Assigned(Interf) then //interface known?
begin
i := List.Count - 1; //search in list of the interfaces
while (i >= 0) and (Interf <> TIdentType(List[i]).GetFinalType) do
Dec(i);
if i < 0 then //not found? => generate warning
FOnUnknownInterface(Self, Interf.Name, Prop, False);
end; //if Assigned(Interf)
end; //if Assigned(FOnUnknownInterface)
end //if Assigned(Interf) and Interf is an interface
else
IdentifierText(One); //just add the text
end; //while Source <> ''
end;
{Will be called for a reference on a method of an implemented interface.
It is used in classes that give another name of a method implementing a method
of an interface (at least that's what I understand by reading the help of that
syntax). The interface and the method should be underlaid with links to their
declarations if possible.
~param Name the interface and its method separated by a dot
~param Method the pseudo-method renaming a method of an implemented interface }
procedure TICDeclarationAssembler.InterfaceMethod(const Name: String;
Method: TIdentifier);
var MethodOf :TRecordType; //class implementing the interface
i :Integer; //general index
Interf :TIdentifier; //the interface of the method
MethodName :String; //the name of the method
Final :TType; //the real interface type
TheInterf :TRecordType; //interface defining the method
TheMethod :TIdentifier; //the implemented method
List :TIdentifierList; //the list of implemented interfaces
begin
Assert(Method is TFunction);
Assert(Assigned(Method.MemberOf));
Assert(Assigned(SourceIdent));
Assert(Assigned(SourceIdent.InFile));
MethodOf := Method.MemberOf; //get class implementing interface
i := Pos('.', Name);
Assert(i <> 0);
//search the interface manually
Interf := FGenerator.FindIdentifier(Copy(Name, 1, i - 1), MethodOf.InFile,
MethodOf.Position);
if Assigned(Interf) and //identifier found and valid kind?
((Interf is TRecordType) or (Interf is TIdentType)) then
begin
CreateLink(Interf); //add link to the interface
IdentifierText('.'); //and the dot
//extract implemented method
MethodName := Copy(Name, i + 1, High(Length(Name)));
Final := TType(Interf);
if Final is TIdentType then //get the final interface type
Final := TIdentType(Final).GetFinalType;
//interface known?
if (Final is TRecordType) and (TRecordType(Final).Kind = rkInterface) then
begin
//search the method in the interface and its ancestors
TheInterf := TRecordType(Final); //interface defining the method
repeat //search the method by its name
TheMethod := TheInterf.IdentList.GetIdentByName(MethodName);
if not Assigned(TheMethod) then //not found?
TheInterf := TheInterf.GetParent; //get parent interface
//until found or no ancestor (known)
until Assigned(TheMethod) or not Assigned(TheInterf);
if Assigned(TheMethod) then //method found?
CreateLink(TheMethod) //add link to the method
else
IdentifierText(MethodName); //just add the name of the method
end
else
IdentifierText(MethodName); //just add the name of the method
//check if it is an implemented interface
if Interf is TIdentType then
Interf := TIdentType(Interf).GetFinalType;
if Assigned(Interf) then
begin
List := MethodOf.Implementing; //get the implemented interfaces
{$IFOPT C+}
for i := 0 to List.Count - 1 do
Assert(List[i] is TIdentType);
{$ENDIF}
if Assigned(FOnUnknownInterface) then //handler for it defined?
begin
i := List.Count - 1; //search in list of the interfaces
while (i >= 0) and (Interf <> TIdentType(List[i]).GetFinalType) do
Dec(i);
if i < 0 then //not found? => generate warning
FOnUnknownInterface(Self, Interf.Name, Method, True);
end; //Assigned(FOnUnknownInterface)
end; //if Assigned(Interf)
end //if identifier found and valid kind
else
IdentifierText(Name); //just use the text
end;
{Will be called for texts with the name of a method of the given record-like
type. It is used in classes that give another name of a method implementing a
method of an interface (at least that's what I understand by reading the help
of that syntax). The method should be underlaid with a link to its declaration
if possible.
~param Name the name of a method in that record-like type
~param MethodOf the record-like type that contains that method }
procedure TICDeclarationAssembler.MethodName(const Name: String;
MethodOf: TRecordType);
var Ident :TIdentifier; //the identifier
begin
Assert(Assigned(SourceIdent));
Assert(Assigned(SourceIdent.InFile));
Assert(Name <> '');
if Assigned(MethodOf) then //only valid in classes
begin
Assert(Pos(' ', Name) = 0);
Assert(Pos('.', Name) = 0);
//search the identifier in the class and its ancestors
Ident := MethodOf.FindMember(Name, MethodOf.InFile, True);
if Assigned(Ident) then //identifier found?
CreateLink(Ident) //generate a link to it
else
IdentifierText(Name); //just add the text
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -