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

📄 udocumentdoc.pas

📁 DelphiDoc is a program for automatic generation of documentation on a Delphi-Project. At the momen
💻 PAS
📖 第 1 页 / 共 5 页
字号:
                 dot := pos('.', Token);
                 if dot = 0 then
                  dot := length(Token);
                end;
               Delete(Token, 1, dot);                //delete the identifier
              end;
            end;

           if assigned(Ident) then               //something found?
            begin
             //while members follow
             while (Token <> '') and (Ident is TRecordType) do
              begin
               dot := pos('.', Token);
               if dot = 0 then                       //get next member
                IdentName := Token
               else
                IdentName := copy(Token, 1, dot - 1);

               RecIdent := TRecordType(Ident);       //search the member
               Ident := RecIdent.FindMember(IdentName, SourceIdent.InFile,
                                            False);
               if assigned(Ident) then               //member found?
                begin
                 if dot = 0 then                       //delete it
                  Token := ''
                 else
                  Delete(Token, 1, dot);

                 //not documented?
                 if DoNotDocumentIdentifier(Ident) then
                  //just add the text
                  Result := Result + IdentifierText(IdentName)
                 else
                  //append a link to it
                  Result := Result + '.' + GetRecordFieldNameLink(Ident);
                end;
              end; //while Token <> '' and Ident is TRecordType

             if Token <> '' then                   //add any unknown members
              Result := Result + '.' + IdentifierText(Token);
            end //if assigned(Ident)
           else
            Result := Result + IdentifierText(Token); //append text
          end //if Next <> ':'   //record-field initialization?
         else
          //link on field of record would be nice, but would have to know the
          //record, hard if its an array of record or record of array etc.
          Result := Result + IdentifierText(Token);
        end //if not 'nil'
      end //if identifier or reserved word
     else
      begin
       if (State <> sBrace) and              //no space after opening brace
          ((length(Token) <> 1) or           //not a single special character?
           (not (Token[1] in [',', '.', '(', ')', ']']) and
            ((Token[1] <> '[') or (State <> sIdent)))) and
          //no spaces between parts of strings
          ((State <> sString) or not (Token[1] in ['''', '#', '^'])) then
        Result := Result + ' ';                     //add a separating space

       if Token[1] = '''' then               //is a string?
        Result := Result + FormatStringToken(Token) //add formatted as string
       else
        Result := Result + HandleRawText(Token);    //add text

       //get state of the expression after this last token
       if Token[1] in ['(', '['] then
        State := sBrace
       else
        if (Token[1] in ['''', '#']) or
           ((Token[1] = '^') and (State <> sIdent)) then
         State := sString
        else
         if Token[1] in [')', ']', '.', '^'] then
          State := sIdent
         else
          State := sNo;

       //needs a second token?
       if (State = sString) and (Token[1] in ['#', '^']) and
          Parser.GetToken(Token) then        //and it is available?
        //add character number or the escaped control character
        Result := Result + HandleRawText(Token);

      end; //else identifier or reserved word
    end; //while Parser.GetIdentWithPointsToken
 finally
  Parser.Free;                           //free tokenizer
 end;
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 returned
~param SourceIdent the identifier from which the description that included this
                   attribute has been requested
~result the member as a link if possible }
function TDocumentDoc.PropertyReadWrite(const ReadWrite: String;
                                        Prop: TProperty;
                                        SourceIdent: TIdentifier): String;
var      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 <> '');
 Result := ReadWrite;
 if assigned(Prop) and assigned(Prop.MemberOf) then
  begin
   //delete all whitespace for simpler parsing
   Result := DeleteAllWhiteSpaces(Result);

   dot := pos('.', Result);               //get first identifier
   if dot <> 0 then
    begin
     IdentName := copy(Result, 1, dot - 1); //extract first identifier
     Delete(Result, 1, dot - 1);            //the remnant (including dot)
    end
   else
    begin
     IdentName := Result;                   //only a simple identifier
     Result := '';
    end;


   //search the identifier in the class
   Ident := Prop.MemberOf.FindMember(IdentName, SourceIdent.InFile, True);
   //check if identifier is not documented
   if assigned(Ident) and DoNotDocumentIdentifier(Ident) then
    Ident := nil;

   if assigned(Ident) then            //identifier found?
    //generate a link on it
    Result := GetRecordFieldNameLink(Ident) + IdentifierText(Result)
   else                                 //just return the text
    Result := IdentifierText(IdentName) + IdentifierText(Result);
  end;
end;

{Will be called for implements-attribute of properties. The interfaces are
 underlaid with a link to their declaration if possible.
~param Prop        the property whose implemented interface should be returned
~param SourceIdent the identifier from which the description that included the
                   property has been requested
~result the implemented interface as a link if possible }
function TDocumentDoc.PropertyImplements(Prop: TProperty;
                                         SourceIdent: TIdentifier): String;
var      Source      :String;           //list of redirected interfaces
         List        :TIdentifierList;  //list of implemented interfaces
         i           :Integer;          //general index
         One, LC     :String;           //each implemented interface
         Interf      :TIdentifier;      //the interface
         Message     :TGeneratorMessage; //the message to add
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}

 Result := '';                          //no text so far
 while Source <> '' do                  //for each interface
  begin
   if Result <> '' then                   //not first interface?
    Result := Result + HandleRawText(', '); //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 := FindIdentifier(One, Prop.InFile, Prop.MemberOf.Position);
   if assigned(Interf) and             //identifier found and valid kind?
      ((Interf is TRecordType) or (Interf is TIdentType)) and
      not DoNotDocumentIdentifier(Interf) then
    begin                                //add link to it
     Result := Result + GetIdentNameLink(Interf, pos('.', One) <> 0);

     //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
        begin
         InitMessage(Message, DocumentDocMessagesID,
                     Ord(ddmkImplementedInterfaceOfPropertyDoesNotMatch),
     Format(DocumentationTexts[dtImplementedInterfaceOfPropertyDoesNotMatch].T,
            [One]));
         Message.Position.Identifier := Prop;
         AddMessage(Message);
        end;
      end;
    end
   else
    Result := Result + IdentifierText(One);  //just add the text
  end;
end;

{Will be called for texts with an implemented interface and one of its methods.
 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 TheName     the interface and its method separated by a dot
~param MethodOf    the class that implements the interface
~param SourceIdent the identifier from that the description that included this
                   method-assigment has been requested
~result the name of the interface and the method as links if possible }
function TDocumentDoc.InterfaceMethod(const TheName: String;
                                      MethodOf: TRecordType;
                                      SourceIdent: TIdentifier): String;
var      Name        :String;          //the name of the method
         i           :Integer;         //general index
         Interf      :TIdentifier;     //the interface of the method
         Final       :TType;           //the real interface type
         TheInterf   :TRecordType;     //interface defining the method
         Method      :TIdentifier;     //the implemented method
         List        :TIdentifierList; //the list of implemented interfaces
         Message     :TGeneratorMessage; //the message to add
begin
 assert(assigned(SourceIdent));
 assert(assigned(SourceIdent.InFile));

 Name := TheName;                      //use the name

 i := pos('.', Name);
 assert(i <> 0);

 //search the interface manually
 Interf := 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)) and
    not DoNotDocumentIdentifier(Interf) then
  begin
   //add link to the interface and the dot
   Result := GetIdentNameLink(Interf) + IdentifierText('.');
   Delete(Name, 1, i);                    //extract implemented method
   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
       Method := TheInterf.IdentList.GetIdentByName(Name); //search method
       if not assigned(Method) then         //get parent interface
        TheInterf := TheInterf.GetParent;
       //until found or no ancestor (known)
     until assigned(Method) or not assigned(TheInterf);

     //method found and documented?
     if assigned(Method) and not DoNotDocumentIdentifier(Method) then
      //add link to the method
      Result := Result + GetRecordFieldNameLink(Method)
     else
      //just add the name of the method
      Result := Result + IdentifierText(Name);
    end
   else
    Result := Result + IdentifierText(Name); //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}
     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
      begin
       InitMessage(Message, DocumentDocMessagesID,
                   Ord(ddmkInterfaceOfMethodNotImplemented),
              Format(DocumentationTexts[dtInterfaceOfMethodNotImplemented].T,
                     [Interf.Name]));
       Message.Position.Identifier := MethodOf;
       AddMessage(Message);
      end;
    end; //if assigned(Interf)
  end //if identifier found and valid kind
 else
  Result := 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
~param SourceIdent the identifier from that the description that included this
                   method-assigment has been requested
~result the name of the method as a link if possible }
function TDocumentDoc.MethodName(const Name: String; MethodOf: TRecordType;
                                 SourceIdent: TIdentifier): String;
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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -