2012-08-03 41 views
9

這是一個典型的複製粘貼錯誤:是否有一個工具可以檢測重複的接口GUID?

如果包含接口聲明與GUID的一些Delphi代碼是複製粘貼,德爾福不會抱怨和編譯代碼,從而重新使用相同的GUID在不同的地方。

「支持」功能基於它們的GUID與接口配合使用,因此可能出現錯誤。

是否有可用於檢測它們的「質量保證」工具(Peganza或Delphi Sonar插件)?

+3

更確切地說,你想要一些檢測GUID用於不同接口定義的東西嗎? GUID可能會出現多次在同一接口的源代碼中。但恕我直言,它是一個編碼錯誤複製和粘貼新的定義,而不是Ctrl + Shift + G。 – 2012-08-03 10:08:43

+4

我不知道PAL有這樣的報告,但它會是一個很好的擴展。我提出了一項功能要求。 – 2012-08-03 10:11:26

回答

1

如果你使用的是UNIX/Mac上試試這個 - 或者,如果您的PC上有cygwin

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

然後找個人複製

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

測試在Mac

+0

公頃 - 沒有意識到這個問題是2歲: - / – daven11 2014-12-20 11:04:50

1

只適用於最新版本的Delphi。您可以使用以下代碼在運行時檢測到這一點:

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. 

當然,如果它符合您的需求。因爲將它包含到生產代碼中並不是最好的想法。但是可以包含在測試代碼中。

相關問題