]> git.saurik.com Git - cycript.git/blobdiff - Analyze.cpp
Add a ?reparse mode to experiment pretty printing.
[cycript.git] / Analyze.cpp
index 49ff5cb5d5c53a04fac2de44e387023544ac80d4..f5195a0b2d2b39e157e6162c5f2825ea60a33823 100644 (file)
@@ -298,6 +298,18 @@ static CYTypedIdentifier *CYDecodeType(CXType type, const CYCXString &identifier
     return typed;
 }
 
     return typed;
 }
 
+static void CYParseEnumeration(CXCursor cursor, CYTypedIdentifier *typed) {
+    CYList<CYEnumConstant> constants;
+
+    CYForChild(cursor, fun([&](CXCursor child) {
+        if (clang_getCursorKind(child) == CXCursor_EnumConstantDecl)
+            constants->*$ CYEnumConstant($I($pool.strdup(CYCXString(child))), $D(clang_getEnumConstantDeclValue(child)));
+    }));
+
+    CYTypedIdentifier *integer(CYDecodeType(clang_getEnumDeclIntegerType(cursor)));
+    typed->specifier_ = $ CYTypeEnum(NULL, integer->specifier_, constants);
+}
+
 static void CYParseStructure(CXCursor cursor, CYTypedIdentifier *typed) {
     CYList<CYTypeStructField> fields;
     CYForChild(cursor, fun([&](CXCursor child) {
 static void CYParseStructure(CXCursor cursor, CYTypedIdentifier *typed) {
     CYList<CYTypeStructField> fields;
     CYForChild(cursor, fun([&](CXCursor child) {
@@ -316,16 +328,14 @@ static void CYParseCursor(CXType type, CXCursor cursor, CYTypedIdentifier *typed
     switch (CXCursorKind kind = clang_getCursorKind(cursor)) {
         case CXCursor_EnumDecl:
             if (spelling[0] != '\0')
     switch (CXCursorKind kind = clang_getCursorKind(cursor)) {
         case CXCursor_EnumDecl:
             if (spelling[0] != '\0')
-                // XXX: should we have a special enum keyword?
-                typed->specifier_ = $ CYTypeVariable($I(spelling.Pool($pool)));
+                typed->specifier_ = $ CYTypeReference(CYTypeReferenceEnum, $I(spelling.Pool($pool)));
             else
             else
-                // XXX: maybe replace with "enum : int" instead of "int"
-                CYParseType(clang_getEnumDeclIntegerType(cursor), typed);
+                CYParseEnumeration(cursor, typed);
         break;
 
         case CXCursor_StructDecl: {
             if (spelling[0] != '\0')
         break;
 
         case CXCursor_StructDecl: {
             if (spelling[0] != '\0')
-                typed->specifier_ = $ CYTypeReference($I(spelling.Pool($pool)));
+                typed->specifier_ = $ CYTypeReference(CYTypeReferenceStruct, $I(spelling.Pool($pool)));
             else
                 CYParseStructure(cursor, typed);
         } break;
             else
                 CYParseStructure(cursor, typed);
         } break;
@@ -408,8 +418,9 @@ static void CYParseType(CXType type, CYTypedIdentifier *typed) {
         break;
 
         case CXType_IncompleteArray:
         break;
 
         case CXType_IncompleteArray:
-            // XXX: I should support these :/
-            _assert(false);
+            // XXX: I probably should not decay to Pointer
+            CYParseType(clang_getArrayElementType(type), typed);
+            typed = typed->Modify($ CYTypePointerTo());
         break;
 
         case CXType_ObjCClass:
         break;
 
         case CXType_ObjCClass:
@@ -444,7 +455,7 @@ static void CYParseType(CXType type, CYTypedIdentifier *typed) {
         break;
 
         case CXType_Record:
         break;
 
         case CXType_Record:
-            typed->specifier_ = $ CYTypeReference($I($pool.strdup(CYCXString(clang_getTypeSpelling(type)))));
+            typed->specifier_ = $ CYTypeReference(CYTypeReferenceStruct, $I($pool.strdup(CYCXString(clang_getTypeSpelling(type)))));
         break;
 
         case CXType_Typedef:
         break;
 
         case CXType_Typedef:
@@ -480,6 +491,7 @@ static CXChildVisitResult CYChildVisit(CXCursor cursor, CXCursor parent, CXClien
     CYChildBaton &baton(*static_cast<CYChildBaton *>(arg));
     CXTranslationUnit &unit(baton.unit);
 
     CYChildBaton &baton(*static_cast<CYChildBaton *>(arg));
     CXTranslationUnit &unit(baton.unit);
 
+    CXChildVisitResult result(CXChildVisit_Continue);
     CYCXString spelling(cursor);
     std::string name(spelling);
     std::ostringstream value;
     CYCXString spelling(cursor);
     std::string name(spelling);
     std::ostringstream value;
@@ -495,6 +507,31 @@ static CXChildVisitResult CYChildVisit(CXCursor cursor, CXCursor parent, CXClien
             value << clang_getEnumConstantDeclValue(cursor);
         } break;
 
             value << clang_getEnumConstantDeclValue(cursor);
         } break;
 
+        case CXCursor_EnumDecl: {
+            if (spelling[0] == '\0')
+                goto skip;
+            // XXX: this was blindly copied from StructDecl
+            if (!clang_isCursorDefinition(cursor))
+                priority = 1;
+
+            CYLocalPool pool;
+
+            CYTypedIdentifier typed(NULL);
+            CYParseEnumeration(cursor, &typed);
+
+            CYOptions options;
+            CYOutput out(*value.rdbuf(), options);
+            CYTypeExpression(&typed).Output(out, CYNoBFC);
+
+            value << ".withName(\"" << name << "\")";
+            name = "$cye" + name;
+            flags = CYBridgeType;
+
+            // the enum constants are implemented separately *also*
+            // XXX: maybe move output logic to function we can call
+            result = CXChildVisit_Recurse;
+        } break;
+
         case CXCursor_MacroDefinition: {
             CXSourceRange range(clang_getCursorExtent(cursor));
             CYTokens tokens(unit, range);
         case CXCursor_MacroDefinition: {
             CXSourceRange range(clang_getCursorExtent(cursor));
             CYTokens tokens(unit, range);
@@ -566,7 +603,7 @@ static CXChildVisitResult CYChildVisit(CXCursor cursor, CXCursor parent, CXClien
             CYTypeExpression(&typed).Output(out, CYNoBFC);
 
             value << ".withName(\"" << name << "\")";
             CYTypeExpression(&typed).Output(out, CYNoBFC);
 
             value << ".withName(\"" << name << "\")";
-            name += "$cy";
+            name = "$cys" + name;
             flags = CYBridgeType;
         } break;
 
             flags = CYBridgeType;
         } break;
 
@@ -636,9 +673,10 @@ static CXChildVisitResult CYChildVisit(CXCursor cursor, CXCursor parent, CXClien
             }
         } break;
 
             }
         } break;
 
-        default: {
-            return CXChildVisit_Recurse;
-        } break;
+        default:
+            result = CXChildVisit_Recurse;
+            goto skip;
+        break;
     } {
         CYKey &key(baton.keys[name]);
         if (key.priority_ <= priority) {
     } {
         CYKey &key(baton.keys[name]);
         if (key.priority_ <= priority) {
@@ -652,7 +690,7 @@ static CXChildVisitResult CYChildVisit(CXCursor cursor, CXCursor parent, CXClien
     }
 
   skip:
     }
 
   skip:
-    return CXChildVisit_Continue;
+    return result;
 }
 
 int main(int argc, const char *argv[]) {
 }
 
 int main(int argc, const char *argv[]) {