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

📄 unamespaces.pas

📁 DelphiDoc is a program for automatic generation of documentation on a Delphi-Project. At the momen
💻 PAS
📖 第 1 页 / 共 2 页
字号:
      FFileParser.CountUnitReference(fpMain, UnitIndex); //count the reference
     end
    else
     begin
      UnitIndex := FThisFile.UsedUnitList[fpInterface].IndexOf(IdentName);
      if UnitIndex <> -1 then                  //is a used unit (not interface)
       begin
        SourceFile := TPascalFile(FThisFile.UsedUnitList[fpInterface].
                                                           Objects[UnitIndex]);
        //count the reference
        FFileParser.CountUnitReference(fpInterface, UnitIndex);
       end
      else
       begin
        //declared in a unit that is used in the interface?
        Result := CheckUsedUnits(FThisFile.UsedUnitList[fpMain], fpMain);
        if not assigned(Result) then           //not found so far?
         //declared in a unit that is used elsewhere(/implementation)?
         Result := CheckUsedUnits(FThisFile.UsedUnitList[fpInterface],
                                  fpInterface);
       end;
     end;
   end;
end;






   { * * *  ***  * * *  ***   TWithNameSpace   ***  * * *  ***  * * *  }


{Creates the namespace object and assigns the record-like type to be searched.
~param RecIdent         the record-like identifier to be searched
~param CurrentFile      the current file with the with-statement
~param IsOrHasInherited if the with-statement is used in the same file as
                        RecIdent is declared or in the class RecIdent
                        (if protected members should be returned) }
constructor TWithNameSpace.Create(RecIdent: TRecordType;
                                  CurrentFile: TPascalFile;
                                  IsOrHasInherited: Boolean);
begin
 inherited Create;                       //create the object

 FRecIdent := RecIdent;                  //save the parameters
 FCurrentFile := CurrentFile;
 FIsOrHasInherited := IsOrHasInherited;
end;


{Searches the identifier in the record-like identifier.
~param IdentName  the name of the identifier to search
~param SourceFile if it is a file and not an identifier, it is returned through
                  this parameter
~result the identifier, if found, or nil }
function TWithNameSpace.FindIdent(const IdentName: String;
                                  var SourceFile: TPascalFile): TIdentifier;
begin
 if assigned(FRecIdent) then      //has to be set for with-namespaces
  begin                           //(but may be not for function-namespaces))

   //search in the record-like identifier (and its parents)
   Result := FRecIdent.FindMember(IdentName, FCurrentFile, FIsOrHasInherited);

   if not assigned(Result) then     //if not found, search previous namespace
    Result := inherited FindIdent(IdentName, SourceFile)
   else
    SourceFile := nil;                //do not also return the file
  end
 else    //no with-identifier (for functions outside classes (no methods))
  begin
   assert(Self is TLocalFuncNameSpace);       //search previous namespace
   Result := inherited FindIdent(IdentName, SourceFile);
  end;
end;






   { * * *  ***  * * *  ***   TLocalFuncNameSpace   ***  * * *  ***  * * *  }


{Creates the namespace object and assigns the function-identifier.
~param FuncIdent the identifier of this function }
constructor TLocalFuncNameSpace.Create(FuncIdent: TFunction);
var         SelfIdent          :TVariable; //identifier for "Self" and result
begin
 //create the object
 inherited Create(FuncIdent.MemberOf, FuncIdent.InFile, True);

 FFuncIdent := FuncIdent;                  //save function-identifier

 FLocalIdents := TIdentifierList.Create;   //create list for local identifiers
 FSpecialList := TIdentifierList.Create;   //and for "Self" and result

 if assigned(FuncIdent.MemberOf) then      //is a method?
  begin
   SelfIdent := TVariable.Create;            //create "Self" as a variable
   try
     SelfIdent.Scope := sLocal;
     SelfIdent.Name := 'Self';
     SelfIdent.VarType := TIdentType.Create; //type is the class of the method
     TIdentType(SelfIdent.VarType).DefIdent := FuncIdent.MemberOf.Name;
     TIdentType(SelfIdent.VarType).TheType := FuncIdent.MemberOf;
     FSpecialList.AddIdent(SelfIdent);       //and add identifier
   except
     SelfIdent.Free;
     raise;
   end;
  end;



 FResultIdent := True;    //assumption is, this is true, but will be set

 if (FFuncIdent.FuncKind = fkFunction) {and
    assigned(FFuncIdent.ReturnType)} then  //if it is a function
  begin
   assert(assigned(FFuncIdent.ReturnType));

   SelfIdent := TVariable.Create;          //create variable "Result"
   try
     SelfIdent.Scope := sLocal;
     SelfIdent.Name := FFuncIdent.Name;    //alias for the name of the function
     SelfIdent.VarType := TType(FFuncIdent.ReturnType.Clone);
     SelfIdent.Position := FFuncIdent.ForwardDefPos;
     FSpecialList.AddIdent(SelfIdent);     //and add identifier
   except
     SelfIdent.Free;
     raise;
   end;
  end;

 FSubLocalIdents := TIdentifierList.Create; //list for internal identifiers


 FUsedIdents := TIdentifierList.Create;     //list for used global identifiers
end;

{Destroys the namespace object. }
destructor TLocalFuncNameSpace.Destroy;
begin
 FSubLocalIdents.Free;         //free list for internal identifiers
 FSpecialList.Free;            //free list for "Self" and result

 FLocalIdents.Free;            //free list for local identifiers

 if assigned(FUsedIdents) then
  FUsedIdents.RemoveAll(False);  //don't free the used identifiers
 FUsedIdents.Free;             //free of used global identifiers
                               //(could be nil (if top-level it should))

 inherited Destroy;            //free the object
end;



{Searches the identifier in the (local) identifiers of the function.
~param IdentName   the name of the identifier to search
~param SourceFile  if it is a file and not an identifier, it is returned
                   through this parameter
~result the identifier, if found, or nil }
function TLocalFuncNameSpace.FindIdent(const IdentName: String;
                                     var SourceFile: TPascalFile): TIdentifier;
var      Name               :String;          //the effective name
begin
 Name := IdentName;                           //use the name

 //if it is a function and the searched identifier "Result"
 if (FFuncIdent.FuncKind = fkFunction) {and
    assigned(FFuncIdent.ReturnType)} and
    FResultIdent and (LowerCase(Name) = 'result') then
  begin
   assert(assigned(FFuncIdent.ReturnType));
   Name := FFuncIdent.Name;                     //use instead the function-name
  end;

 Result := FSpecialList.GetIdentByName(Name);      //"Self" or "Result"?
 if not assigned(Result) then
  begin
   Result := FFuncIdent.Params.GetIdentByName(Name); //a parameter?
   if not assigned(Result) then
    Result := FLocalIdents.GetIdentByName(Name);     //locally defined?
  end;

 if not assigned(Result) then
  //search in "Self" and in previous namespace
  Result := inherited FindIdent(Name, SourceFile)
 else
  SourceFile := nil;                            //do not also return the file
end;


{Adds an identifier that is defined inside the function (in an
 except-on-clause).
~param Ident the identifier defined inside the function }
procedure TLocalFuncNameSpace.AddSubLocalIdent(Ident: TIdentifier);
begin
 FSubLocalIdents.AddIdent(Ident);  //add the identifier to the internal list
 FUsedIdents.RemoveIdent(Ident, False); //remove from the list; it's not global
end;

{Adds the identifier to the list of used global identifiers. The identifier is
 only added if it's not local and not already in the list.
~param Ident the in this function used global identifier }
procedure TLocalFuncNameSpace.AddUsedIdent(Ident: TIdentifier);
begin
 if not FSpecialList.RecursiveIsIn(Ident) and      //not "Self" or "Result"?
    not FSubLocalIdents.RecursiveIsIn(Ident) and   //not an exception-variable?
    not FLocalIdents.RecursiveIsIn(Ident) and      //not a local identifier?
    not FFuncIdent.Params.RecursiveIsIn(Ident) and //not a parameter?
    not FUsedIdents.IsIn(Ident) then               //not already in the list?
  FUsedIdents.AddIdent(Ident);                       //add it to the list
end;

{Adds all in this (nested) function used global identifiers to the list of used
 global identifiers of the given function-namespace (the namespace of the
 function, this function is defined in).
~param NameSpace the namespace to which all used global identifiers should be
                 added }
procedure TLocalFuncNameSpace.MoveGlobalIdentsTo(NameSpace:
                                                          TLocalFuncNameSpace);
var       i                  :Integer;      //counter through the identifiers
begin
 for i := 0 to FUsedIdents.Count - 1 do     //for each used global identifier
  NameSpace.AddUsedIdent(FUsedIdents[i]);     //get and add it
end;

{Moves the list of used identifiers to the function-identifier. }
procedure TLocalFuncNameSpace.MoveGlobalsToFunction;
begin
 assert(not assigned(FFuncIdent.UsedIdents));
 FFuncIdent.SetUsedIdentsList(FUsedIdents); //move the list to the identifier
 FUsedIdents := nil;                        //don't free it anymore
end;







   { * * *  ***  * * *  ***   TOnExceptNameSpace   ***  * * *  ***  * * *  }


{Creates the namespace object and creates the exception-variable.
~param Name     the name of the exception-variable
~param ThisFile the file of the exception-variable (of the function)
~param ExcName  the name of the type of the exception
~param ExcIdent identifier of the type of the exception (or nil) }
constructor TOnExceptNameSpace.Create(const Name: String;
                                      ThisFile: TPascalFile;
                                      const ExcName: String;
                                      ExcIdent: TRecordType);
begin
 inherited Create;                       //create the object

 FLCName := LowerCase(Name);             //save for faster comparison

 FVariable := TVariable.Create;          //create the variable
 FVariable.Name := Name;                 //assign the name
 FVariable.InFile := ThisFile;
 FVariable.VarType := TIdentType.Create; //create the type of the exception
 with TIdentType(FVariable.VarType) do
  begin
   if assigned(ExcIdent) then              //set the name of the type
    DefIdent := ExcIdent.Name
   else
    DefIdent := ExcName;
   TheType := ExcIdent;                    //set the type of the exception
  end;
end;

{Destroys the namespace object and moves the exception-variable to the
 function-namespace. This has to be done because there may be references to it
 (shouldn't be, but possible anyway). }
destructor TOnExceptNameSpace.Destroy;
var        NameSpace         :TNameSpace;  //to search the function-namespace
begin
 NameSpace := FPreNameSpace;               //search the next function-namespace
 while assigned(NameSpace) and not (NameSpace is TLocalFuncNameSpace) do
  NameSpace := NameSpace.PreNameSpace;
 assert(assigned(NameSpace));
 //add the exception-variable to the namespace (it won't be freed here)
 TLocalFuncNameSpace(NameSpace).AddSubLocalIdent(FVariable);

 inherited Destroy;                        //free the object
end;


{Searches the identifier by comparing it to the exception-variable.
~param IdentName   the name of the identifier to search
~param SourceFile  if it is a file and not an identifier, it is returned
                   through this parameter
~result the identifier, if found, or nil }
function TOnExceptNameSpace.FindIdent(const IdentName: String;
                                     var SourceFile: TPascalFile): TIdentifier;
begin
 if LowerCase(IdentName) = FLCName then  //it's this exception-variable?
  begin
   SourceFile := nil;                      //not a file
   Result := FVariable;                    //return the variable
  end
 else                                    //search in previous namespace
  Result := inherited FindIdent(IdentName, SourceFile);
end;

end.

⌨️ 快捷键说明

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