2012-08-03 26 views
9

Đây là một điển hình copy-paste lỗi:Có một công cụ phát hiện GUIDs giao diện trùng lặp?

nếu một số mã Delphi chứa khai báo giao diện với GUID là copy-dán, Delphi sẽ không phàn nàn và biên dịch mã mà lại sử dụng cùng một GUID ở những nơi khác nhau.

Các "Hỗ trợ" chức năng làm việc với giao diện dựa trên GUID của họ, do sai sót có thể xảy ra.

Có một 'đảm bảo chất lượng' công cụ có sẵn (Peganza hoặc plugin Delphi Sonar có thể) có thể phát hiện chúng?

+3

Để được chính xác hơn, bạn muốn một cái gì đó mà phát hiện rằng một GUID được sử dụng để định nghĩa giao diện đa dạng? GUID có thể xuất hiện nhiều lần trong mã nguồn cho cùng một giao diện. Nhưng IMHO nó là một lỗi mã hóa để sao chép và dán cho một định nghĩa mới thay vì Ctrl + Shift + G. –

+4

Tôi không biết rằng PAL có một báo cáo như vậy, nhưng nó sẽ là một phần mở rộng thoải mái với nó. Tôi đã thực hiện một yêu cầu tính năng. –

Trả lời

1

Nếu bạn đang ở trên một unix/mac thử này - hoặc nếu bạn có cygwin trên máy tính của bạn

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

Sau đó, để tìm ra cá nhân trùng lặp

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

Thử nghiệm trên một mac

+0

ha - không nhận ra câu hỏi này là 2 tuổi: - / – daven11

1

Chỉ làm việc với các phiên bản gần đây của Delphi. Bạn có thể sử dụng đoạn mã sau để phát hiện này tại thời gian chạy:

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. 

Tất nhiên nếu nó phù hợp với nhu cầu của bạn. Vì đó không phải là ý tưởng tốt nhất để đưa mã này vào mã sản xuất. Tuy nhiên có thể được bao gồm trong mã kiểm tra.

Các vấn đề liên quan