2013-07-20 13 views
5

Próbuję wyodrębnić nazwę klasy parametru do wywołania metody w Obiektyw-C. Kod mam parsowania jest:libclang uzyskać nazwę klasy od kursora

- (void)testAddConcreteDataModel:(DFDemoDataModelOne*)helpmeh { 
    [self.dataModels addObject:helpmeh]; 
} 

A wynik muszę to typ klasy helpmeh, czyli „DFDemoDataModelOne”.

Dotychczas Mam następujący kod, który Wyjścia: "[(DFDataModelContainer).dataModels addObject:helpmeh]"

if (cursor.kind == CXCursor_ObjCMessageExpr) { 
     __block NSString* memberName = nil; 
     __block NSString* ownerClassName = nil; 
     __block NSString* methodName = [NSString stringWithUTF8String:clang_getCString(clang_getCursorDisplayName(cursor))]; 

     clang_visitChildrenWithBlock(cursor, ^enum CXChildVisitResult(CXCursor cursor, CXCursor parent) { 
      if (cursor.kind == CXCursor_MemberRefExpr) { 
       memberName = [NSString stringWithUTF8String:clang_getCString(clang_getCursorDisplayName(cursor))]; 
       ownerClassName = [NSString stringWithUTF8String:clang_getCString(clang_getCursorDisplayName(clang_getCursorSemanticParent(clang_getCursorReferenced(cursor))))]; 
      } else { 
       if (memberName) { 
        NSString* param = [NSString stringWithUTF8String:clang_getCString(clang_getCursorDisplayName(cursor))]; 
        NSLog(@"[(%@).%@ %@%@]", ownerClassName, memberName, methodName, param); 
        clang_visitChildrenWithBlock(cursor, ^enum CXChildVisitResult(CXCursor cursor, CXCursor parent) { 

         // test 
         if ([param isEqualToString:@"helpmeh"] && cursor.kind == CXCursor_DeclRefExpr) { 
          // found the interesting part.. what now? 
         } 
         return CXChildVisit_Recurse; 
        } 
       } 
      } 
      return CXChildVisit_Continue; 
     } 
    } 

Jestem tylko trochę zagubiony, jak wydobyć informacje z cursors- kiedy AST zrzucić moją klasę widzę informacji Potrzebuję ich wszystkich (patrz ostatnia linia):

|-ObjCMethodDecl 0x112790f90 <line:32:1, line:34:1> - testAddConcreteDataModel: 'void' 
    | |-ImplicitParamDecl 0x112791960 <<invalid sloc>> self 'DFDataModelContainer *const __strong' 
    | |-ImplicitParamDecl 0x1127919c0 <<invalid sloc>> _cmd 'SEL':'SEL *' 
    | |-ParmVarDecl 0x112791040 <line:32:35, col:55> helpmeh 'DFDemoDataModelOne *__strong' 
    | `-CompoundStmt 0x112791bf0 <col:63, line:34:1> 
    | `-ExprWithCleanups 0x112791bd8 <line:33:5, col:39> 'void' 
    |  `-ObjCMessageExpr 0x112791ba0 <col:5, col:39> 'void' selector=addObject: 
    |  |-PseudoObjectExpr 0x112791b48 <col:6, col:11> 'NSMutableArray *' 
    |  | |-ObjCPropertyRefExpr 0x112791ad0 <col:6, col:11> '<pseudo-object type>' lvalue objcproperty Kind=PropertyRef Property="dataModels" Messaging=Getter 
    |  | | `-OpaqueValueExpr 0x112791ab0 <col:6> 'DFDataModelContainer *' 
    |  | | `-ImplicitCastExpr 0x112791a40 <col:6> 'DFDataModelContainer *' <LValueToRValue> 
    |  | |  `-DeclRefExpr 0x112791a18 <col:6> 'DFDataModelContainer *const __strong' lvalue ImplicitParam 0x112791960 'self' 'DFDataModelContainer *const __strong' 
    |  | |-OpaqueValueExpr 0x112791ab0 <col:6> 'DFDataModelContainer *' 
    |  | | `-ImplicitCastExpr 0x112791a40 <col:6> 'DFDataModelContainer *' <LValueToRValue> 
    |  | | `-DeclRefExpr 0x112791a18 <col:6> 'DFDataModelContainer *const __strong' lvalue ImplicitParam 0x112791960 'self' 'DFDataModelContainer *const __strong' 
    |  | `-ImplicitCastExpr 0x112791b30 <col:11> 'NSMutableArray *' <ARCReclaimReturnedObject> 
    |  | `-ObjCMessageExpr 0x112791b00 <col:11> 'NSMutableArray *' selector=dataModels 
    |  |  `-OpaqueValueExpr 0x112791ab0 <col:6> 'DFDataModelContainer *' 
    |  |  `-ImplicitCastExpr 0x112791a40 <col:6> 'DFDataModelContainer *' <LValueToRValue> 
    |  |   `-DeclRefExpr 0x112791a18 <col:6> 'DFDataModelContainer *const __strong' lvalue ImplicitParam 0x112791960 'self' 'DFDataModelContainer *const __strong' 
    |  `-ImplicitCastExpr 0x112791b88 <col:32> 'id':'id' <BitCast> 
    |   `-ImplicitCastExpr 0x112791b70 <col:32> 'DFDemoDataModelOne *' <LValueToRValue> 
    |   `-DeclRefExpr 0x112791a88 <col:32> 'DFDemoDataModelOne *__strong' lvalue ParmVar 0x112791040 'helpmeh' 'DFDemoDataModelOne *__strong' 

Wszelkie wskazówki są mile widziane!

Odpowiedz

0

myślę Znalazłem Roztwór podstawowy

  • Get definicji kursora (w powyższym przypadku było CXCursor_ParmDecl ale może to być cokolwiek, jak CXCursor_VarDecl itp
  • Get pierwsze dziecko tego kursora

Tu jest mój zaktualizowany Code to Hacky i potrzebuje trochę oczyszczania/wyjaśnienia, ale publikuje tutaj dla potomności.

- (void)processMethodDeclaration:(const CXIdxDeclInfo *)declaration { 
    clang_visitChildrenWithBlock(declaration->cursor, ^enum CXChildVisitResult(CXCursor cursor, CXCursor parent) { 

     if (cursor.kind == CXCursor_ObjCMessageExpr) { 
      __block NSString* memberName = nil; 
      __block NSString* referencedObjectName = nil; 

      clang_visitChildrenWithBlock(cursor, ^enum CXChildVisitResult(CXCursor cursor, CXCursor parent) { 
       if (cursor.kind == CXCursor_MemberRefExpr) { 
        memberName = [NSString stringWithUTF8String:clang_getCString(clang_getCursorDisplayName(cursor))]; 
        referencedObjectName = [NSString stringWithUTF8String:clang_getCString(clang_getCursorDisplayName(clang_getCursorSemanticParent(clang_getCursorReferenced(cursor))))]; 
       } else { 
        if (memberName) { 
         __block NSString* passedClassName = nil; 

         clang_visitChildrenWithBlock(cursor, ^enum CXChildVisitResult(CXCursor cursor, CXCursor parent) { 
          if (cursor.kind == CXCursor_DeclRefExpr) { 
           CXCursor def = clang_getCursorDefinition(cursor); 
           clang_visitChildrenWithBlock(def, ^enum CXChildVisitResult(CXCursor cursor, CXCursor parent) { 
            passedClassName = [NSString stringWithUTF8String:clang_getCString(clang_getCursorDisplayName(cursor))]; 
            return CXChildVisit_Break; 
           }); 
          } 

          return CXChildVisit_Recurse; 
         }); 

         return CXChildVisit_Break; 
        } 
       } 
       return CXChildVisit_Continue; 
      }); 
     } 
     return CXChildVisit_Recurse; 
    }); 
} 
+1

zadowolony, że znalazł rozwiązanie ... Jeśli mam trochę czasu, postaram się sprawdzić dokładny zachowanie getCursorSemanticParent: jeśli nie ma to zastosowania w twoim przypadku, naprawdę coś w tym jest źle zrozumiałem! – Francesco

+0

w Pythonie C++ (powiązanie python clang) również wydaje się, że rodzic semantyczny kursora delkacji metody jest NoneType. Jest to bardzo niewygodne. to musi być błąd. –

+0

W porządku Skłamałem, działa idealnie, ale powiązanie z pythonem jest oznaczone jako @property, więc nie ma nawiasów podczas wywoływania 'semantic_parent' i wow, to działa. –

3

Czy próbowałeś spojrzeć na funkcję clang_getCursorSemanticParent?

Nie mogę pomóc z kodem objc, ale ogólna idea powinno być coś takiego:

  1. rozmowy clang_getCursorSemanticParent uzyskać kursor do deklaracji klasy
  2. połączeń clang_getCursorSpelling lub clang_getCursorDisplayName w deklaracji klasy kursor, aby uzyskać nazwę klasy
+0

tak myślałem, ale semantyczny rodzic wydaje się po prostu wrócić kursor z rodzaju CXCursor_FirstInvalid ... – Sam

Powiązane problemy