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

📄 uparse.pas

📁 DelphiDoc is a program for automatic generation of documentation on a Delphi-Project. At the momen
💻 PAS
📖 第 1 页 / 共 5 页
字号:
     begin
      Name := ExtractShortPathName(ExpandFileName(Name));
      if Name <> '' then                      //directory exists?
       Dirs.AddObject(Name, List.Objects[i])    //add to list of directories
     end;
   end;
 end;

var       AddFiles      :TStrings;    //list of files to parse
          //list of directories to search for files to parse
          AddDirs       :TStrings;
          //list of files not to parse when found (in/by AddDirs)
          SubFiles      :TStrings;
          //list of directories not to search when searching (in/by AddDirs)
          SubDirs       :TStrings;
begin
 AddFiles := TStringList.Create;
 try
   AddDirs := TStringList.Create;
   try
     FProgress.SetWorkText('Splitting list of files/directories...');


     //split list of files and directories to parse
     SplitLists(Parse, AddFiles, AddDirs);

     SubFiles := TStringList.Create;
     try
       SubDirs := TStringList.Create;
       try
         FProgress.SetWorkText('Splitting list of ignored files/directories...');

         //split list of files and directories not to parse
         SplitLists(NotParse, SubFiles, SubDirs);


         FProgress.SetWorkText('Parsing files and directories...');

         //parse all files and the files in the directories
         ParseList(AddFiles, AddDirs, SubFiles, SubDirs);


       finally
        SubDirs.Free;
       end;
     finally
      SubFiles.Free;
     end;
   finally
    AddDirs.Free;
   end;
 finally
  AddFiles.Free;
 end;
end;

{Parses all units the files use (in their interfaces). }
procedure TParserManager.ParseAllUsedUnits;
var       Count         :Integer;     //number of parsed files
          i             :Integer;     //counter through parsed files
          FileD         :TPascalFile; //each file to be parsed
begin
 repeat                               //as long as no new files found

   Count := List.Count;                 //get number of parsed files

   FProgress.Reset;
   FProgress.SetWorkText('Parsing first uses-clause...');
   FProgress.SetMaximum(Count);

   for i := 0 to Count - 1 do           //for each file
    begin
     FileD := List[i];                    //get the file

     FProgress.SetProgressText(Format('Parsing file %d of %d',
                                     [i + 1, Count]));
     FProgress.SetProcessText(FileD.InternalFileName);

     if TFileParser(FileD.Parser).ParseState =
        psInterfaceUsesClauseParsed then //not parsed yet?
      //parse its used units (in the interface)
      TFileParser(FileD.Parser).ParseInterfaceUsedUnits;

     FProgress.StepProgress;
    end;

 until List.Count = Count;            //until no new files (from Libs)
end;


{Parses all units the files use and interfaces of units. }
procedure TParserManager.ParseInterfacesAndUsedUnits;
var       Count         :Integer;         //number of parsed files
          i             :Integer;         //counter through parsed files
          FileD         :TPascalFile;     //each file to be parsed
begin
 repeat                                   //until no new files (from Libs)

   //parse all units the files use (in their interfaces)
   ParseAllUsedUnits;

   //sort the files into the right order for parsing
   SortFileList(List);



   FProgress.Reset;
   FProgress.SetWorkText('Parsing interface-section...');

   Count := List.Count;                     //get number of parsed files
   for i := 0 to Count - 1 do               //for each file
    begin
     FileD := List[i];                        //get the file

     FProgress.SetProgressText(Format('Parsing file %d of %d', [i + 1, Count]));
     FProgress.SetProcessText(FileD.InternalFileName);

     if TFileParser(FileD.Parser).ParseState =      //not parsed yet?
        psInterfaceUnitsParsed then
      //parse the interface-section and the uses-clause of
      //the implementation section if it is a unit
      TFileParser(FileD.Parser).ParseInterface;

     FProgress.StepProgress;
    end;



   FProgress.Reset;
   FProgress.SetWorkText('Parsing later uses-clause and linking interface...');

   for i := 0 to Count - 1 do               //for each file
    begin
     FileD := List[i];                        //get the file

     FProgress.SetProgressText(Format('Parsing file %d of %d', [i + 1, Count]));
     FProgress.SetProcessText(FileD.InternalFileName);

     //not parsed yet?
     if TFileParser(FileD.Parser).ParseState = psInterfaceParsed then
      //parse its used units (in case it's a unit parse also the interface)
      TFileParser(FileD.Parser).
                              LinkUnitInterfaceAndParseImplementationUsedUnits;

     FProgress.StepProgress;
    end;


 until List.Count = Count;                //until no new files (from Libs)
end;



{Encapsulates the parsing of several pascal-files. This function provides a
 simple way to call the various functions and methods of different classes in
 the right sequence. }
procedure TParserManager.DoParseFiles;
var       i, j          :Integer;     //general counter
          Count         :Integer;     //number of parsed files
          FileD         :TPascalFile; //a file of pascal code to be parsed
          //counter through the kind of record-likes
          rk            :TRecordKind;

          Index         :Integer;     //index in identifiers with the same name
          S             :String;      //name of an identifier for comparison
          //for test of identifiers (functions & record-like) with the same
          IdentList     :TIdentifierList;                            //name
          //for test of identifiers with the same name
          Ident         :TIdentifier;
          SearchIndex   :Integer;     //index to resume the search

          //portability issues of the file
          Portability      :TIdentPortabilities;
begin
 //initialize FProgress-object
 FProgress.Reset;
 FProgress.SetThrowExceptionOnStepIfAbort(True);

 FProgress.SetWorkText('Adding predefined Identifiers...');
 FProgress.SetProgressText('');
 FProgress.SetProcessText('');

 FProgress.SetMaximum(10);

 //add list of predefined identifiers
{
 if FileExists('PreDefinedIdents.txt') then
  TFileParser.GetPreDefinedIdentList.LoadFromFile('PreDefinedIdents.txt');
 if FileExists('SystemTypes.txt') then
  TFileParser.GetSystemTypeList.LoadFromFile('SystemTypes.txt');
 if FileExists('SystemIdents.txt') then
  TFileParser.GetSystemIdentList.LoadFromFile('SystemIdents.txt');
}


 //create the list for the files to parse only if used by other files
 GetLibList;

 if assigned(Parse) then              //new files to parse specified?
  ParseNewFiles;                        //parse them

 //parse all units the files use and interfaces of units
 ParseInterfacesAndUsedUnits;

 Count := List.Count;                 //get number of parsed files



 FProgress.Reset;
 FProgress.SetWorkText('Consistence in hierarchy of record-likes...');

 for i := 0 to Count - 1 do           //for each file
  begin
   FileD := List[i];                    //get the file

   FProgress.SetProgressText(Format('Parsing file %d of %d', [i + 1, Count]));
   FProgress.SetProcessText(FileD.InternalFileName);

   //check all public (in the interface declared) record-like types
   TFileParser(FileD.Parser).ConsistencyAfterRecordHierarchy;

   FProgress.StepProgress;
  end;

 FProgress.Reset;
 FProgress.SetWorkText('Parsing Implementation...');
 for i := 0 to Count - 1 do           //for each file
  begin
   FileD := List[i];                    //get the file

   FProgress.SetProgressText(Format('Parsing file %d of %d', [i + 1, Count]));
   FProgress.SetProcessText(FileD.InternalFileName);

   //parse the code of the file
   TFileParser(FileD.Parser).ParseImplementations;

   FProgress.StepProgress;
  end;

 FProgress.Reset;
 FProgress.SetWorkText('Consistence of record-likes after parsing...');
 for i := 0 to Count - 1 do           //for each file
  begin
   FileD := List[i];                    //get the file

   FProgress.SetProgressText(Format('Parsing file %d of %d', [i + 1, Count]));
   FProgress.SetProcessText(FileD.InternalFileName);

   //sorts the different lists of identifiers
   TFileParser(FileD.Parser).ConsistencyAfterParse;

   FProgress.StepProgress;
  end;


 FProgress.Reset;
 FProgress.SetWorkText('Generating cross-reference...');

 for i := 0 to Count - 1 do           //for each file
  begin
   FileD := List[i];                    //get the file

   FProgress.SetProgressText(Format('Generating with file %d of %d',
                                   [Count - i, Count]));
   FProgress.SetProcessText(FileD.InternalFileName);

   //check if correct state of parsing
   TFileParser(FileD.Parser).DoCheckParseState(psFinalConsistency);

   //generate cross-references (for function-identifiers; used by ~)
   for j := 0 to FileD.Idents.Count - 1 do
    begin
     //generate cross-reference
     Ident := FileD.Idents[j].GenerateCrossReference;
     if Assigned(Ident) then        //function without body found?
      TFileParser(FileD.Parser).ExceptionIdentFmt(Ident, etSyntax,
                                                  'No implementation/body found for function "%s"!',
                                                  [Ident.Name]);
    end;

   //set new state of parsing
   TFileParser(FileD.Parser).ParseState := psCrossReferences;


   FProgress.StepProgress;
  end;



 FProgress.Reset;
 FProgress.SetWorkText('Inheriting portability issues...');

 for i := 0 to Count - 1 do           //for each file
  begin
   FileD := List[i];                    //get the file

   FProgress.SetProgressText(Format('Inheriting in file %d of %d',
                                   [Count - i, Count]));
   FProgress.SetProcessText(FileD.InternalFileName);



   //check if correct state of parsing
   TFileParser(FileD.Parser).DoCheckParseState(psCrossReferences);

   //get portability issues of the file
   Portability := FileD.Portability;

   //let all identifier inherit portability issues
   for j := 0 to FileD.Idents.Count - 1 do
    FileD.Idents[j].AddPortabilityIssues(Portability);

   //set new state of parsing
   TFileParser(FileD.Parser).ParseState := psPortabilityIssuesInheritedFirst;

   //second time for enumeration items
   for j := 0 to FileD.Idents.Count - 1 do
    FileD.Idents[j].AddPortabilityIssues(Portability);

   //set new state of parsing
   TFileParser(FileD.Parser).ParseState :=
                                       psPortabilityIssuesInheritedEnumeration;


   FProgress.StepProgress;
  end;















 FProgress.Reset;
 FProgress.SetWorkText('Testing of double names...');

 for i := 0 to Count - 1 do           //for each file
  begin
   FileD := List[i];                    //get the file

   FProgress.SetProgressText(Format('Testing file %d of %d',
                                   [Count - i, Count]));
   FProgress.SetProcessText(FileD.InternalFileName);

   //test if internal name corresponds to name of file
   TestFileName(FileD);

   Index := 0;
   S := LowerCase(FileD.InternalFileName);   //get (internal) name of file
   for j := i + 1 to Count - 1 do                 //compare to each others name
    if LowerCase(List[j].InternalFileName) = S then
     inc(Index);
   FileD.InternalNameIndex := Index;         //numerate files with same name

   //add a warning, the first time, the name is doubled encountered
   if Index = 1 then                         //i.e. the second time
    AddWarning(Format('Files with same internal name: %s',
                      [FileD.InternalFileName]),
               TFileParser(FileD.Parser));

   FProgress.StepProgress;
  end;


 FProgress.Reset;
 FProgress.SetWorkText('Testing of double names...');
 FProgress.SetMaximum(Count * (ord(high(rk)) - ord(low(rk)) + 1 + 1));

 IdentList := TIdentifierList.Create;     //create list for all identifiers
 try
   for rk := high(rk) downto low(rk) do   //for each kind of record-like types
    begin

⌨️ 快捷键说明

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