From a07efabcc54bea23707c4fa5e558f68f90ce42fa Mon Sep 17 00:00:00 2001 From: Daniel Gavin Date: Thu, 30 Dec 2021 02:32:35 +0100 Subject: refractor with bitsets, and fix inlined struct/union/enum --- src/analysis/analysis.odin | 63 ++++++++++++++++++++++++++++++++++++++-------- src/index/collector.odin | 15 ++++++++--- src/index/symbol.odin | 15 ++++++++--- src/server/completion.odin | 7 +++--- 4 files changed, 78 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/analysis/analysis.odin b/src/analysis/analysis.odin index b6f4e70..09bfb3a 100644 --- a/src/analysis/analysis.odin +++ b/src/analysis/analysis.odin @@ -538,12 +538,12 @@ is_symbol_same_typed :: proc(ast_context: ^AstContext, a, b: index.Symbol, flags return false; } - if a.is_distinct != b.is_distinct { + if .Distinct in a.flags != .Distinct in b.flags { return false; } - if a.is_distinct == b.is_distinct && - a.is_distinct == true && + if .Distinct in a.flags == .Distinct in b.flags && + .Distinct in a.flags && a.name == b.name && a.pkg == b.pkg { return true; @@ -829,6 +829,14 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (i using ast; switch v in &node.derived { + case Union_Type: + return make_symbol_union_from_ast(ast_context, v, ast_context.field_name, true), true; + case Enum_Type: + return make_symbol_enum_from_ast(ast_context, v, ast_context.field_name, true), true; + case Struct_Type: + return make_symbol_struct_from_ast(ast_context, v, ast_context.field_name, true), true; + case Bit_Set_Type: + return make_symbol_bitset_from_ast(ast_context, v, ast_context.field_name, true), true; case Array_Type: return make_symbol_array_from_ast(ast_context, v), true; case Dynamic_Array_Type: @@ -1113,7 +1121,7 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (i if is_distinct { return_symbol.name = node.name; - return_symbol.is_distinct = is_distinct; + return_symbol.flags |= {.Distinct}; } return return_symbol, ok; @@ -1171,7 +1179,7 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (i if is_distinct { return_symbol.name = node.name; - return_symbol.is_distinct = is_distinct; + return_symbol.flags |= {.Distinct}; } return_symbol.doc = common.get_doc(global.docs, context.temp_allocator); @@ -1579,7 +1587,9 @@ make_symbol_procedure_from_ast :: proc(ast_context: ^AstContext, n: ^ast.Node, v } if expr, ok := ast_context.globals[name]; ok { - symbol.is_deprecated = expr.deprecated; + if expr.deprecated { + symbol.flags |= {.Distinct}; + } } symbol.value = index.SymbolProcedureValue { @@ -1658,7 +1668,7 @@ make_symbol_basic_type_from_ast :: proc(ast_context: ^AstContext, n: ^ast.Node, return symbol; } -make_symbol_union_from_ast :: proc(ast_context: ^AstContext, v: ast.Union_Type, ident: string) -> index.Symbol { +make_symbol_union_from_ast :: proc(ast_context: ^AstContext, v: ast.Union_Type, ident: string, inlined := false) -> index.Symbol { symbol := index.Symbol { range = common.get_token_range(v, ast_context.file.src), @@ -1666,6 +1676,11 @@ make_symbol_union_from_ast :: proc(ast_context: ^AstContext, v: ast.Union_Type, pkg = get_package_from_node(v.node), }; + if inlined { + symbol.flags |= {.Anonymous}; + symbol.name = "union"; + } + names := make([dynamic]string, context.temp_allocator); for variant in v.variants { @@ -1689,14 +1704,19 @@ make_symbol_union_from_ast :: proc(ast_context: ^AstContext, v: ast.Union_Type, return symbol; } -make_symbol_enum_from_ast :: proc(ast_context: ^AstContext, v: ast.Enum_Type, ident: string) -> index.Symbol { - +make_symbol_enum_from_ast :: proc(ast_context: ^AstContext, v: ast.Enum_Type, ident: string, inlined := false) -> index.Symbol { symbol := index.Symbol { range = common.get_token_range(v, ast_context.file.src), type = .Enum, pkg = get_package_from_node(v.node), }; + if inlined { + symbol.flags |= {.Anonymous}; + symbol.name = "enum"; + } + + names := make([dynamic]string, context.temp_allocator); for n in v.fields { @@ -1719,7 +1739,7 @@ make_symbol_enum_from_ast :: proc(ast_context: ^AstContext, v: ast.Enum_Type, id return symbol; } -make_symbol_bitset_from_ast :: proc(ast_context: ^AstContext, v: ast.Bit_Set_Type, ident: string) -> index.Symbol { +make_symbol_bitset_from_ast :: proc(ast_context: ^AstContext, v: ast.Bit_Set_Type, ident: string, inlined := false) -> index.Symbol { symbol := index.Symbol { range = common.get_token_range(v, ast_context.file.src), @@ -1727,6 +1747,11 @@ make_symbol_bitset_from_ast :: proc(ast_context: ^AstContext, v: ast.Bit_Set_Typ pkg = get_package_from_node(v.node), }; + if inlined { + symbol.flags |= {.Anonymous}; + symbol.name = "bitset"; + } + symbol.value = index.SymbolBitSetValue { expr = v.elem, bitset_name = ident, @@ -1735,7 +1760,7 @@ make_symbol_bitset_from_ast :: proc(ast_context: ^AstContext, v: ast.Bit_Set_Typ return symbol; } -make_symbol_struct_from_ast :: proc(ast_context: ^AstContext, v: ast.Struct_Type, ident: string) -> index.Symbol { +make_symbol_struct_from_ast :: proc(ast_context: ^AstContext, v: ast.Struct_Type, ident: string, inlined := false) -> index.Symbol { symbol := index.Symbol { range = common.get_token_range(v, ast_context.file.src), @@ -1743,6 +1768,11 @@ make_symbol_struct_from_ast :: proc(ast_context: ^AstContext, v: ast.Struct_Type pkg = get_package_from_node(v.node), }; + if inlined { + symbol.flags |= {.Anonymous}; + symbol.name = "struct"; + } + names := make([dynamic]string, context.temp_allocator); types := make([dynamic]^ast.Expr, context.temp_allocator); usings := make(map[string]bool, 0, context.temp_allocator); @@ -2505,6 +2535,17 @@ get_call_commas :: proc(position_context: ^DocumentPositionContext, document: ^c position_context.call_commas = commas[:]; } +type_to_string :: proc(ast_context: ^AstContext, expr: ^ast.Expr) -> string { + + if symbol, ok := resolve_type_expression(ast_context, expr); ok { + if .Anonymous in symbol.flags { + return symbol.name; + } + } + + return common.node_to_string(expr); +} + /* Figure out what exactly is at the given position and whether it is in a function, struct, etc. */ diff --git a/src/index/collector.odin b/src/index/collector.odin index 74c47e1..11e949a 100644 --- a/src/index/collector.odin +++ b/src/index/collector.odin @@ -371,9 +371,18 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri symbol.pkg = get_index_unique_string(collection, directory); symbol.type = token_type; symbol.doc = common.get_doc(expr.docs, collection.allocator); - symbol.is_deprecated = expr.deprecated; - symbol.is_private_file = expr.file_private; - symbol.is_private_package = expr.package_private; + + if expr.deprecated { + symbol.flags |= {.Deprecated}; + } + + if expr.file_private { + symbol.flags |= {.PrivateFile}; + } + + if expr.package_private { + symbol.flags |= {.PrivatePackage}; + } when ODIN_OS == "windows" { symbol.uri = get_index_unique_string(collection, strings.to_lower(uri, context.temp_allocator)); diff --git a/src/index/symbol.odin b/src/index/symbol.odin index 8e13786..e2ebad5 100644 --- a/src/index/symbol.odin +++ b/src/index/symbol.odin @@ -102,6 +102,16 @@ SymbolValue :: union { SymbolUntypedValue, } +SymbolFlag :: enum { + Distinct, + Deprecated, + PrivateFile, + PrivatePackage, + Anonymous, +} + +SymbolFlags :: bit_set[SymbolFlag] + Symbol :: struct { range: common.Range, uri: string, @@ -114,10 +124,7 @@ Symbol :: struct { value: SymbolValue, references: []common.Location, pointers: int, - is_distinct: bool, - is_deprecated: bool, - is_private_file: bool, - is_private_package: bool, + flags: SymbolFlags, } SymbolType :: enum { diff --git a/src/server/completion.odin b/src/server/completion.odin index b9d17a9..ce0e872 100644 --- a/src/server/completion.odin +++ b/src/server/completion.odin @@ -408,7 +408,6 @@ get_selector_completion :: proc(ast_context: ^analysis.AstContext, position_cont if symbol, ok := resolve_type_expression(ast_context, v.types[i]); ok { if expr, ok := position_context.selector.derived.(ast.Selector_Expr); ok { - if expr.op.text == "->" && symbol.type != .Function { continue; } @@ -421,7 +420,7 @@ get_selector_completion :: proc(ast_context: ^analysis.AstContext, position_cont item := CompletionItem { label = name, kind = .Field, - detail = fmt.tprintf("%v.%v: %v", selector.name, name, common.node_to_string(v.types[i])), + detail = fmt.tprintf("%v.%v: %v", selector.name, name, type_to_string(ast_context, v.types[i])), documentation = symbol.doc, }; @@ -463,7 +462,7 @@ get_selector_completion :: proc(ast_context: ^analysis.AstContext, position_cont item.insertText = fmt.tprintf("%v($0)", item.label); item.insertTextFormat = .Snippet; item.command.command = "editor.action.triggerParameterHints"; - item.deprecated = symbol.is_deprecated; + item.deprecated = .Deprecated in symbol.flags; } append(&items, item); @@ -1041,7 +1040,7 @@ get_identifier_completion :: proc(ast_context: ^analysis.AstContext, position_co if result.symbol.type == .Function { item.insertText = fmt.tprintf("%v($0)", item.label); item.insertTextFormat = .Snippet; - item.deprecated = result.symbol.is_deprecated; + item.deprecated = .Deprecated in result.symbol.flags; item.command.command = "editor.action.triggerParameterHints"; } -- cgit v1.2.3