2012-08-03 13 views
9

Questo è un tipico errore di copia-incolla:Esiste uno strumento che rileva GUID di interfaccia duplicati?

se qualche codice Delphi contenente dichiarazioni di interfaccia con GUID è incollato copia, Delphi non si lamentano e compilare codice che riutilizza lo stesso GUID in luoghi diversi.

La funzione "Supporti" funziona con interfacce basate sul GUID, quindi gli errori sono possibili.

C'è uno strumento di 'garanzia di qualità' disponibile (Peganza o il plug-in Sonar Delphi forse) in grado di rilevarli?

+3

Per essere più precisi, si desidera qualcosa che rileva che un GUID viene utilizzato per la definizione di diverse interfacce? Il GUID può apparire più volte nel codice sorgente per la stessa interfaccia. Ma IMHO è un errore di codifica da copiare e incollare per una nuova definizione invece di Ctrl + Shift + G. –

+4

Non sono a conoscenza del fatto che PAL abbia un tale rapporto, ma sarebbe una buona estensione. Ho fatto una richiesta di funzionalità. –

risposta

1

Se siete su un sistema Unix/mac provare questo - o se si dispone di cygwin sul PC

find . -name '*.pas' -exec awk "/\['{.*}'\]/ {print $1}" {} \; | sed 's/ //g' | sort | uniq -d 

Poi per trovare l'individuo duplica

find . -name '*.pas' -exec grep -i -l 'XXXX-XXX-XXX' {} \; 

Testato su un mac

+0

ha - non si rendeva conto che questa domanda aveva 2 anni: - / – daven11

1

Funziona solo con la versione recente di Delphi. È possibile utilizzare il seguente codice per rilevare questo a run-time:

unit uInterfaces.Duplicates; 

interface 

uses 
    System.Rtti, 
    Spring, 
    Spring.Collections; 

type 
    /// <summary> 
    /// Class allows to list the interfaces which are not implemented by any class in your module. 
    /// </summary> 
    InterfacesWithDuplicateGUID = class 
    private class var 
    /// <summary> 
    /// Reference to the RTTI context. 
    /// </summary> 
    FCtx: TRttiContext; 
    public 
    /// <summary> 
    /// Function returns the list of interfaces with duplicate GUID. 
    /// </summary> 
    /// <param name="AFilter"> 
    /// A filter predicate for types to process. 
    /// </param> 
    class function Map(AFilter: TPredicate<TRttiInterfaceType> = nil): IMultiMap<TGUID, TRttiInterfaceType>; 

    class constructor Create; 
    class destructor Destroy; 
    end; 

implementation 

uses 
    System.TypInfo; 

{ InterfacesNotImplemented } 

class constructor InterfacesWithDuplicateGUID.Create; 
begin 
    FCtx := TRttiContext.Create; 
end; 

class destructor InterfacesWithDuplicateGUID.Destroy; 
begin 
    FCtx.Free; 
end; 

class function InterfacesWithDuplicateGUID.Map(AFilter: TPredicate<TRttiInterfaceType> = nil): IMultiMap<TGUID, TRttiInterfaceType>; 
var 
    LType: TRttiType; 
    LIntf: TRttiInterfaceType; 
    LTypes: IList<TRttiInterfaceType>; 
begin 
    { Create the result instance } 
    Result := TCollections.CreateMultiMap<TGUID, TRttiInterfaceType>; 

    { Get all the types } 
    LTypes := TCollections.CreateList<TRttiInterfaceType>; 

    { Build the multimap } 
    for LType in FCtx.GetTypes do 
    { Add only classes and interfaces } 
    if LType.TypeKind = tkInterface then 
     { Skip interfaces which does not have GUID } 
     if TRttiInterfaceType(LType).GUID <> TGUID.Empty then 
     begin 
      { Handle user filter } 
      if Assigned(AFilter) then 
      if not AFilter(TRttiInterfaceType(LType)) then 
       Continue; 

      LTypes.Add(TRttiInterfaceType(LType)); 
     end; 

    { For all interaces } 
    for LIntf in LTypes do 
    if LTypes.Any(
     function (const AType: TRttiInterfaceType): Boolean 
     begin 
     Result := (AType.GUID = LIntf.GUID) and (LIntf.QualifiedName <> AType.QualifiedName); 
     end) then 
     Result.Add(LIntf.GUID, LIntf); 
end; 

end. 

Naturalmente se si adatta alle tue esigenze. Poiché non è la migliore idea includere questo nel codice di produzione. Tuttavia può essere incluso nel codice di prova.

Problemi correlati