aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBradley Lewis <22850972+BradLewis@users.noreply.github.com>2025-08-30 21:12:05 -0400
committerGitHub <noreply@github.com>2025-08-30 21:12:05 -0400
commitae1deef16ed49225f06ddaa14f6559efa7309a4c (patch)
tree1a8fa6c41c0c22aba7582e51abe272f70dd6ee9b
parente9a88954b6df0e72b19a0ec6af92e8d24a200511 (diff)
parenta1578111de566bfc524a7f7ac0846da58a06c07b (diff)
Merge pull request #948 from BradLewis/feat/collect-comp-lit-fields
Collect global comp lit fields and add them to workspace and document symbols
-rw-r--r--src/server/collector.odin35
-rw-r--r--src/server/document_symbols.odin39
-rw-r--r--src/server/memory_index.odin16
-rw-r--r--src/server/symbol.odin2
4 files changed, 92 insertions, 0 deletions
diff --git a/src/server/collector.odin b/src/server/collector.odin
index 6e0ffff..4588a39 100644
--- a/src/server/collector.odin
+++ b/src/server/collector.odin
@@ -411,6 +411,28 @@ collect_generic :: proc(
return value
}
+add_comp_lit_fields :: proc(
+ collection: ^SymbolCollection,
+ generic: ^SymbolGenericValue,
+ comp_lit_type: ^ast.Comp_Lit,
+ package_map: map[string]string,
+ file: ast.File,
+) {
+ names := make([dynamic]string, 0, len(comp_lit_type.elems), collection.allocator)
+ ranges := make([dynamic]common.Range, 0, len(comp_lit_type.elems), collection.allocator)
+ for elem in comp_lit_type.elems {
+ if field_value, ok := elem.derived.(^ast.Field_Value); ok {
+ if ident, ok := field_value.field.derived.(^ast.Ident); ok {
+ name := get_index_unique_string(collection, ident.name)
+ append(&names, name)
+ append(&ranges, common.get_token_range(field_value, file.src))
+ }
+ }
+ }
+ generic.field_names = names[:]
+ generic.ranges = ranges[:]
+}
+
collect_method :: proc(collection: ^SymbolCollection, symbol: Symbol) {
pkg := &collection.packages[symbol.pkg]
@@ -646,6 +668,19 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri
} else {
token_type = .Unresolved
}
+ case ^ast.Comp_Lit:
+ generic := collect_generic(collection, col_expr, package_map, uri)
+
+ if expr.mutable {
+ token_type = .Variable
+ } else {
+ token_type = .Unresolved
+ }
+
+ token = expr.expr
+
+ add_comp_lit_fields(collection, &generic, v, package_map, file)
+ symbol.value = generic
case:
// default
symbol.value = collect_generic(collection, col_expr, package_map, uri)
diff --git a/src/server/document_symbols.odin b/src/server/document_symbols.odin
index d146e6a..3571716 100644
--- a/src/server/document_symbols.odin
+++ b/src/server/document_symbols.odin
@@ -76,6 +76,45 @@ get_document_symbols :: proc(document: ^Document) -> []DocumentSymbol {
symbol.kind = .Function
case ^ast.Enum_Type, ^ast.Union_Type:
symbol.kind = .Enum
+ case ^ast.Comp_Lit:
+ if s, ok := resolve_type_expression(&ast_context, v); ok {
+ name_map := make(map[string]common.Range)
+ for elem in v.elems {
+ if field_value, ok := elem.derived.(^ast.Field_Value); ok {
+ if name, ok := field_value.field.derived.(^ast.Ident); ok {
+ name_map[name.name] = common.get_token_range(field_value, ast_context.file.src)
+ }
+ }
+ }
+ #partial switch v in s.value {
+ case SymbolStructValue:
+ children := make([dynamic]DocumentSymbol, context.temp_allocator)
+ for name, i in v.names {
+ child: DocumentSymbol
+ if range, ok := name_map[name]; ok {
+ child.range = range
+ child.selectionRange = range
+ child.name = name
+ child.kind = .Field
+ append(&children, child)
+ }
+ }
+ symbol.children = children[:]
+ case SymbolBitFieldValue:
+ children := make([dynamic]DocumentSymbol, context.temp_allocator)
+ for name, i in v.names {
+ child: DocumentSymbol
+ if range, ok := name_map[name]; ok {
+ child.range = range
+ child.selectionRange = range
+ child.name = name
+ child.kind = .Field
+ append(&children, child)
+ }
+ }
+ symbol.children = children[:]
+ }
+ }
case:
symbol.kind = .Variable
}
diff --git a/src/server/memory_index.odin b/src/server/memory_index.odin
index 7853203..4176757 100644
--- a/src/server/memory_index.odin
+++ b/src/server/memory_index.odin
@@ -95,6 +95,22 @@ memory_index_fuzzy_search :: proc(
append(&symbols, result)
}
}
+ case SymbolGenericValue:
+ for name, i in v.field_names {
+ full_name := fmt.tprintf("%s.%s", symbol.name, name)
+ if score, ok := common.fuzzy_match(fuzzy_matcher, full_name); ok == 1 {
+ s := symbol
+ s.name = full_name
+ s.type = .Field
+ s.range = v.ranges[i]
+ result := FuzzyResult {
+ symbol = s,
+ score = score,
+ }
+
+ append(&symbols, result)
+ }
+ }
}
}
if score, ok := common.fuzzy_match(fuzzy_matcher, symbol.name); ok == 1 {
diff --git a/src/server/symbol.odin b/src/server/symbol.odin
index 3a4b7c6..2090f3b 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -162,6 +162,8 @@ SymbolPolyTypeValue :: struct {
*/
SymbolGenericValue :: struct {
expr: ^ast.Expr,
+ field_names: []string,
+ ranges: []common.Range,
}
SymbolValue :: union {