2012-08-03 26 views
9

Este es un error típico de copiar y pegar:¿Hay alguna herramienta que detecte GUID duplicados?

si algún código de Delphi que contiene declaraciones de interfaz con el GUID es copia-pegar, Delphi no se quejará y compilar código que reutiliza el mismo GUID en diferentes lugares.

La función "Soporta" funciona con interfaces basadas en su GUID, por lo que los errores son posibles.

¿Existe una herramienta de 'control de calidad' disponible (Peganza o el complemento Delphi Sonar tal vez) que pueda detectarlos?

+3

Para ser más precisos, ¿quieres algo que detecte que se usa un GUID para una definición de interfaz diversa? El GUID puede aparecer varias veces en el código fuente para la misma interfaz. Pero en mi humilde opinión, es un error de codificación copiar y pegar para una nueva definición en lugar de Ctrl + Shift + G. –

+4

No soy consciente de que PAL tiene dicho informe, pero sería una buena extensión. He hecho una solicitud de función. –

Respuesta

1

Si estás en un Unix/Mac probar esto - o si tiene cygwin en su PC

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

Luego de encontrar a la persona duplica

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

Probado en un mac

+0

ha - no se dio cuenta de que esta pregunta tenía 2 años de antigüedad: - / – daven11

1

Solo funciona con la versión más reciente de Delphi. Se puede utilizar el siguiente código para detectar esta en tiempo de ejecución:

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. 

Por supuesto, si se ajusta a sus necesidades. Como no es la mejor idea incluir esto en el código de producción. Sin embargo, se puede incluir en el código de prueba.

Cuestiones relacionadas