Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fast completions for Objective-C WIP.

  • Loading branch information...
commit 8ef55ed6c2021964e3d5e827222a8a4dce919d5e 1 parent 20a639c
@quarnster authored
View
14 clang/cindex.py
@@ -1132,7 +1132,8 @@ def get_resolved_cursor(self):
#print "get_type"
if self.kind == CursorKind.STRUCT_DECL or \
self.kind == CursorKind.CLASS_DECL or \
- self.kind == CursorKind.CLASS_TEMPLATE:
+ self.kind == CursorKind.CLASS_TEMPLATE or \
+ self.kind == CursorKind.OBJC_INTERFACE_DECL:
return self
if self.kind == CursorKind.TYPEDEF_DECL:
children = self.get_children()
@@ -1220,6 +1221,9 @@ def get_returned_cursor(self):
if self.kind == CursorKind.FUNCTION_DECL or \
self.kind == CursorKind.FIELD_DECL or \
self.kind == CursorKind.CXX_METHOD or \
+ self.kind == CursorKind.OBJC_INSTANCE_METHOD_DECL or \
+ self.kind == CursorKind.OBJC_CLASS_METHOD_DECL or \
+ self.kind == CursorKind.OBJC_PROPERTY_DECL or \
self.kind == CursorKind.VAR_DECL or \
self.kind == CursorKind.PARM_DECL:
children = self.get_children()
@@ -1240,6 +1244,8 @@ def get_returned_cursor(self):
if c.kind != CursorKind.NAMESPACE_REF:
reference = c.get_reference()
definition = reference.get_definition()
+ if definition is None:
+ definition = reference
if definition is None or definition == c:
return None
@@ -1285,12 +1291,12 @@ def get_returned_cursor(self):
def get_member(self, membername, function):
#print "want to get the cursor for: %s->%s%s" % (self.spelling, membername, "()" if function else "")
for child in self.get_children():
- if function and child.kind == CursorKind.CXX_METHOD and child.spelling == membername:
+ if function and (child.kind == CursorKind.CXX_METHOD or child.kind == CursorKind.OBJC_INSTANCE_METHOD_DECL) and child.spelling == membername:
return child
elif not function and (child.kind == CursorKind.FIELD_DECL or child.kind == CursorKind.VAR_DECL) and child.spelling == membername:
return child
- elif child.spelling == membername:
- print "unhandled kind: %s" % child.kind
+ #elif child.spelling == membername:
+ # print "unhandled kind: %s" % child.kind
# Not found in this class, try base class
for child in self.get_children():
if child.kind == CursorKind.CXX_BASE_SPECIFIER:
View
BIN  libcache.dylib
Binary file not shown
2  parsehelp
@@ -1 +1 @@
-Subproject commit c3bed3511294ab63c3ed5eabd4ab83aab6a8cbd5
+Subproject commit 8db93041cd3a23568ccab437df78ecdc103f6aac
View
6 src/main.cpp
@@ -224,6 +224,7 @@ void get_return_type(std::string& returnType, CXCursorKind ck)
case CXCursor_MacroDefinition: returnType = "macro"; break;
case CXCursor_Namespace: returnType = "namespace"; break;
case CXCursor_TypedefDecl: returnType = "typedef"; break;
+ case CXCursor_ObjCInterfaceDecl: returnType = "interface"; break;
}
}
@@ -382,6 +383,7 @@ class Entry
{
case CXCursor_CXXMethod: isStatic = clang_CXXMethod_isStatic(c); break;
case CXCursor_VarDecl: isStatic = true; break;
+ case CXCursor_ObjCClassMethodDecl: isStatic = true; break;
default: isStatic = false; break;
}
}
@@ -535,6 +537,10 @@ void add_completion_children(CXCursor cursor, CXCursorKind ck, bool &recurse, Co
recurse = true;
// fall through
case CXCursor_Namespace:
+ case CXCursor_ObjCInterfaceDecl:
+ case CXCursor_ObjCPropertyDecl:
+ case CXCursor_ObjCClassMethodDecl:
+ case CXCursor_ObjCInstanceMethodDecl:
case CXCursor_ClassTemplate:
case CXCursor_ClassDecl:
case CXCursor_CXXMethod:
View
13 sublimeclang.sublime-project
@@ -37,5 +37,16 @@
"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
"working_dir": "${project_path}"
}
- ]
+ ],
+ "settings":
+ {
+ "sublimeclang_options":
+ [
+ "-I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/llvm-gcc-4.2/lib/gcc/i686-apple-darwin11/4.2.1/include/",
+ "-isysroot",
+ "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/",
+ "-F/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/System/Library/Frameworks",
+ "-ICocoa"
+ ]
+ }
}
View
66 translationunitcache.py
@@ -226,8 +226,8 @@ def complete(self, data, prefix):
before = line[:-len(prefix)]
ret = None
- if re.search("::$", before):
- match = re.search("([^\(\\s,]+::)+$", before)
+ if re.search(r"::$", before):
+ match = re.search(r"([^\(\s,]+::)+$", before)
if match == None:
ret = None
cached_results = cache_complete_startswith(self.cache, prefix)
@@ -278,7 +278,7 @@ def complete(self, data, prefix):
ret.append((c.display, c.insert))
cache_disposeCompletionResults(comp)
return ret
- elif re.search("([^ \t]+)(\.|\->)$", before):
+ elif re.search(r"(\[[\w]+(\s+[^\]]+\]+)?\s+$|([^ \t]+)(\.|\->)$)", before):
comp = data
if len(prefix) > 0:
comp = data[:-len(prefix)]
@@ -328,11 +328,12 @@ def complete(self, data, prefix):
member = cursor.get_member(typename, func)
cursor, template, pointer = self.solve_member(data, cursor, member, template)
if cursor is None or cursor.kind.is_invalid():
- # Is it by any chance a struct variable?
+ # Is it by any chance a struct variable or an ObjC class?
cursor = self.find_type(data, template[0])
if cursor is None or cursor.kind.is_invalid() or \
cursor.spelling != typename or \
- cursor.kind != cindex.CursorKind.VAR_DECL:
+ (cursor.kind != cindex.CursorKind.VAR_DECL and \
+ cursor.kind != cindex.CursorKind.OBJC_INTERFACE_DECL):
cursor = None
if not cursor is None and not cursor.kind.is_invalid():
# It's going to be a declaration of some kind, so
@@ -345,13 +346,19 @@ def complete(self, data, prefix):
if r is None or \
not (r.kind == cindex.CursorKind.CLASS_DECL or \
r.kind == cindex.CursorKind.STRUCT_DECL or \
+ r.kind == cindex.CursorKind.OBJC_INTERFACE_DECL or \
r.kind == cindex.CursorKind.CLASS_TEMPLATE):
r = None
break
count += 1
match = re.search(r"^([^\.\-\(:\[\]]+)?(\[\]|\(|\.|->|::)(.*)", tocomplete)
if match == None:
- break
+ if "]" in tocomplete:
+ # probably Objective C code
+ match = re.search(r"^\s+(\S+)(\s+)(.*)", tocomplete)
+
+ if match == None:
+ break
tocomplete = match.group(3)
count = 1
@@ -393,6 +400,9 @@ def complete(self, data, prefix):
member = match.group(1)
if "[" in member:
member = get_base_type(member)
+ if "]" in member:
+ function = True
+ member = member[:member.find("]")]
member = r.get_member(member, function)
r, template, pointer = self.solve_member(data, r, member, template)
if r is None and not member is None:
@@ -402,7 +412,7 @@ def complete(self, data, prefix):
if match.group(2) != "(":
tocomplete = match.group(2) + tocomplete
- if not r is None and not r.kind.is_invalid() and pointer == 0:
+ if not r is None and not r.kind.is_invalid() and (pointer == 0 or r.kind == cindex.CursorKind.OBJC_INTERFACE_DECL):
clazz = extract_class_from_function(data)
if clazz == None:
clazz = extract_class(data)
@@ -422,23 +432,31 @@ def complete(self, data, prefix):
replaces.append((r"(^|,|\(|\d:|\s+)(%s)($|,|\s+|\))" % tempnames[i], r"\1%s\3" % s))
if comp and len(comp[0]):
ret = []
- for c in comp[0]:
- if not c.static and c.cursor.kind != cindex.CursorKind.ENUM_CONSTANT_DECL and \
- c.cursor.kind != cindex.CursorKind.ENUM_DECL and \
- c.cursor.kind != cindex.CursorKind.TYPEDEF_DECL and \
- c.cursor.kind != cindex.CursorKind.CLASS_DECL and \
- c.cursor.kind != cindex.CursorKind.STRUCT_DECL and \
- c.cursor.kind != cindex.CursorKind.CLASS_TEMPLATE and \
- (c.access == cindex.CXXAccessSpecifier.PUBLIC or \
- (selfcompletion and not (c.baseclass and c.access == cindex.CXXAccessSpecifier.PRIVATE))):
- disp = c.display
- ins = c.insert
- for r in replaces:
- disp = re.sub(r[0], r[1], disp)
- ins = re.sub(r[0], r[1], ins)
- add = (disp, ins)
- if add not in ret:
- ret.append(add)
+ if r.kind == cindex.CursorKind.OBJC_INTERFACE_DECL:
+ isStatic = var == None
+ for c in comp[0]:
+ if c.static == isStatic:
+ add = (c.display, c.insert)
+ if add not in ret:
+ ret.append(add)
+ else:
+ for c in comp[0]:
+ if not c.static and c.cursor.kind != cindex.CursorKind.ENUM_CONSTANT_DECL and \
+ c.cursor.kind != cindex.CursorKind.ENUM_DECL and \
+ c.cursor.kind != cindex.CursorKind.TYPEDEF_DECL and \
+ c.cursor.kind != cindex.CursorKind.CLASS_DECL and \
+ c.cursor.kind != cindex.CursorKind.STRUCT_DECL and \
+ c.cursor.kind != cindex.CursorKind.CLASS_TEMPLATE and \
+ (c.access == cindex.CXXAccessSpecifier.PUBLIC or \
+ (selfcompletion and not (c.baseclass and c.access == cindex.CXXAccessSpecifier.PRIVATE))):
+ disp = c.display
+ ins = c.insert
+ for r in replaces:
+ disp = re.sub(r[0], r[1], disp)
+ ins = re.sub(r[0], r[1], ins)
+ add = (disp, ins)
+ if add not in ret:
+ ret.append(add)
cache_disposeCompletionResults(comp)
return ret
else:
View
17 unittests/8.mm
@@ -0,0 +1,17 @@
+@interface Hello
+{
+}
++ classMethod;
++ classMethod2;
+- objMethod1;
+- objMethod2;
+@end
+
+@interface World
+{
+ Hello* world;
+}
+- (Hello*) world;
+- (void) setWorld:(Hello*) world;
+@end
+
View
BIN  unittests/gold.txt.gz
Binary file not shown
View
25 unittests/unittest.py
@@ -117,8 +117,11 @@ def get_tu(filename):
currfile = filename
myopts = []
myopts.extend(opts)
- myopts.append("-x")
- myopts.append("c++")
+ if filename.endswith(".cpp"):
+ myopts.append("-x")
+ myopts.append("c++")
+ else:
+ myopts.append("-ObjC")
return translationunitcache.tuCache.get_translation_unit(filename, myopts)
# ---------------------------------------------------------
@@ -307,6 +310,8 @@ def get_tu(filename):
add_test("void Child::something() { MyStaticClass::")
add_test("void Child::something() { Child::")
+# ---------------------------------------------------------
+
tu = get_tu("unittests/7.cpp")
add_test("A a; a.")
add_test("AArray.")
@@ -332,6 +337,22 @@ def get_tu(filename):
add_test(data + "t.")
add_test(data + "t->")
+# ---------------------------------------------------------
+
+opts = [
+ "-I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/llvm-gcc-4.2/lib/gcc/i686-apple-darwin11/4.2.1/include/",
+ "-isysroot",
+ "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/",
+ "-F/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/System/Library/Frameworks",
+ "-ICocoa"]
+tu = get_tu("unittests/8.mm")
+add_test(" ", True)
+add_test("[Hello ")
+add_test("Hello * h; [h ")
+add_test("World * w; [w ")
+add_test("World * w; [[w world] ")
+add_test("World * w; [[w blah] ")
+
if (testsAdded or update) and not dryrun:
f = gzip.GzipFile(GOLDFILE, "wb")
Please sign in to comment.
Something went wrong with that request. Please try again.