⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uicdeclarationassembler.pas

📁 DelphiDoc is a program for automatic generation of documentation on a Delphi-Project. At the momen
💻 PAS
📖 第 1 页 / 共 3 页
字号:
       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 + -