aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2023-01-24 12:21:38 +0100
committerGitHub <noreply@github.com>2023-01-24 12:21:38 +0100
commit4605d64accc56bf9406388d32e4612c4f2ea3543 (patch)
tree22f7a38422c56e9f9fadadebcc2f3366347f0406
parent0024759da37e17611e1b91510bc2b6939c9cb310 (diff)
parent425a81e728aabed07d46c22c1f1dfae5958b8b62 (diff)
Merge pull request #170 from Lperlind/objc-branch
More accurately auto complete ObjC procedures
-rw-r--r--src/common/ast.odin19
-rw-r--r--src/server/analysis.odin6
-rw-r--r--src/server/collector.odin8
-rw-r--r--src/server/completion.odin12
-rw-r--r--src/server/symbol.odin1
5 files changed, 41 insertions, 5 deletions
diff --git a/src/common/ast.odin b/src/common/ast.odin
index c589f49..158882d 100644
--- a/src/common/ast.odin
+++ b/src/common/ast.odin
@@ -143,13 +143,26 @@ get_attribute_objc_class_name :: proc(
}
-get_attribute_objc_class_method :: proc(
+get_attribute_objc_is_class_method :: proc(
attributes: []^ast.Attribute,
) -> (
bool,
- bool,
) {
- return false, false
+ for attribute in attributes {
+ for elem in attribute.elems {
+ if assign, ok := elem.derived.(^ast.Field_Value); ok {
+ if ident, ok := assign.field.derived.(^ast.Ident);
+ ok && ident.name == "objc_is_class_method" {
+ if field_value, ok := assign.value.derived.(^ast.Ident);
+ ok && field_value.name == "true" {
+ return true
+ }
+ }
+
+ }
+ }
+ }
+ return false
}
unwrap_pointer :: proc(expr: ^ast.Expr) -> (ast.Ident, bool) {
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index df6ce4a..ff42709 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -2472,6 +2472,9 @@ make_symbol_procedure_from_ast :: proc(
if _, ok := common.get_attribute_objc_name(attributes); ok {
symbol.flags |= {.ObjC}
+ if common.get_attribute_objc_is_class_method(attributes) {
+ symbol.flags |= {.ObjCIsClassMethod}
+ }
}
return symbol
@@ -2766,6 +2769,9 @@ make_symbol_struct_from_ast :: proc(
if _, ok := common.get_attribute_objc_class_name(attributes); ok {
symbol.flags |= {.ObjC}
+ if common.get_attribute_objc_is_class_method(attributes) {
+ symbol.flags |= {.ObjCIsClassMethod}
+ }
}
if v.poly_params != nil {
diff --git a/src/server/collector.odin b/src/server/collector.odin
index e34458c..89ec7f6 100644
--- a/src/server/collector.odin
+++ b/src/server/collector.odin
@@ -140,7 +140,7 @@ collect_procedure_fields :: proc(
objc_name = common.get_attribute_objc_name(
attributes,
) or_else "",
- objc_is_class_method = common.get_attribute_objc_class_method(
+ objc_is_class_method = common.get_attribute_objc_is_class_method(
attributes,
) or_else false,
*/
@@ -547,6 +547,9 @@ collect_symbols :: proc(
if _, is_objc := common.get_attribute_objc_name(expr.attributes);
is_objc {
symbol.flags |= {.ObjC}
+ if common.get_attribute_objc_is_class_method(expr.attributes) {
+ symbol.flags |= {.ObjCIsClassMethod}
+ }
}
case ^ast.Proc_Type:
token = v^
@@ -584,6 +587,9 @@ collect_symbols :: proc(
expr.attributes,
); is_objc {
symbol.flags |= {.ObjC}
+ if common.get_attribute_objc_is_class_method(expr.attributes) {
+ symbol.flags |= {.ObjCIsClassMethod}
+ }
}
case ^ast.Enum_Type:
token = v^
diff --git a/src/server/completion.odin b/src/server/completion.odin
index 7c3b397..d81aac7 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -519,10 +519,20 @@ get_selector_completion :: proc(
}
}
- if position_context.arrow && symbol.type != .Function {
+ if position_context.arrow {
+ if symbol.type != .Function {
+ continue
+ }
+ if .ObjCIsClassMethod in symbol.flags {
+ assert(.ObjC in symbol.flags)
+ continue
+ }
+ }
+ if !position_context.arrow && .ObjC in symbol.flags {
continue
}
+
item := CompletionItem {
label = name,
kind = .Field,
diff --git a/src/server/symbol.odin b/src/server/symbol.odin
index dffa10a..ce3509d 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -131,6 +131,7 @@ SymbolFlag :: enum {
Variable, //Symbols that are variable, this means their value decl was mutable
Local,
ObjC,
+ ObjCIsClassMethod, // should be set true only when ObjC is enabled
}
SymbolFlags :: bit_set[SymbolFlag]