2012-08-03 3 views
9

일반적인 복사 - 붙여 넣기 오류입니다 :중복 인터페이스 GUID를 감지하는 도구가 있습니까?

GUID가있는 인터페이스 선언이 포함 된 일부 Delphi 코드에 복사 붙여 넣기가있는 경우 Delphi는 다른 위치에서 동일한 GUID를 다시 사용하는 코드를 컴파일하고 컴파일하지 않습니다.

"지원"기능은 GUID를 기반으로하는 인터페이스에서 작동하므로 오류가 발생할 수 있습니다.

그들을 검색 할 수있는 '품질 보증'도구 (Peganza 또는 Delphi Sonar 플러그인)가 있습니까?

+3

더 정확히 말해서, 다양한 인터페이스 정의에 GUID가 사용되는 것을 감지하는 무언가가 필요합니까? GUID는 동일한 인터페이스의 소스 코드에 여러 번 나타날 수 있습니다. 하지만 IMHO는 Ctrl + Shift + G 대신 새로운 정의를 복사하여 붙여 넣기하는 코딩 오류입니다. –

+4

PAL에 그러한 보고서가 있다는 것을 알지 못하지만 좋은 확장이 될 것입니다. 기능 요청을했습니다. –

답변

1

당신이 유닉스/맥에 있다면 이것을 시도 - 또는 당신이 당신의 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' {} \; 

중복 찾을

+0

하 -이 질문이 2 살이라는 것을 알지 못함 : - / – daven11

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. 

물론 필요한 경우. 이것을 프로덕션 코드에 포함시키는 것이 가장 좋은 아이디어는 아닙니다. 그러나 테스트 코드에 포함될 수 있습니다.

관련 문제