aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorBradley Lewis <22850972+BradLewis@users.noreply.github.com>2025-09-21 12:22:45 -0400
committerGitHub <noreply@github.com>2025-09-21 12:22:45 -0400
commit1009de179a717c8b355acb8b1268fedc9b2d089c (patch)
treea9728e212a63dc84c9f1ed0e2a567ce62687375c /src/server
parenta79efd27be8e6951aaa5b7e4bd785121e857c32c (diff)
parent225b794cd3bbb0f116a4cf6e389aa5194c5eca46 (diff)
Merge pull request #1028 from BradLewis/feat/rework-const-hover-info
Feat/rework const hover info
Diffstat (limited to 'src/server')
-rw-r--r--src/server/analysis.odin5
-rw-r--r--src/server/ast.odin6
-rw-r--r--src/server/collector.odin2
-rw-r--r--src/server/documentation.odin116
-rw-r--r--src/server/hover.odin1
-rw-r--r--src/server/signature.odin1
-rw-r--r--src/server/symbol.odin2
7 files changed, 115 insertions, 18 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 20c7749..1e570b4 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -1348,6 +1348,7 @@ resolve_soa_selector_field :: proc(
if resolved, ok := resolve_type_expression(ast_context, v.types[i]); ok {
resolved.pkg = symbol.name
resolved.range = v.ranges[i]
+ resolved.type = .Field
return resolved, ok
} else {
return {}, false
@@ -1902,6 +1903,9 @@ resolve_global_identifier :: proc(ast_context: ^AstContext, node: ast.Ident, glo
return_symbol.comment = get_comment(global.comment)
}
+ return_symbol.type_expr = global.type_expr
+ return_symbol.value_expr = global.value_expr
+
return return_symbol, ok
}
@@ -2615,6 +2619,7 @@ resolve_type_location_proc_param_name :: proc(
symbol.type_name = symbol.name
symbol.pkg = call_symbol.name
symbol.name = ident.name
+ symbol.type = .Field
return symbol, true
}
}
diff --git a/src/server/ast.odin b/src/server/ast.odin
index 91c413f..edb9007 100644
--- a/src/server/ast.odin
+++ b/src/server/ast.odin
@@ -93,6 +93,8 @@ GlobalExpr :: struct {
name: string,
name_expr: ^ast.Expr,
expr: ^ast.Expr,
+ type_expr: ^ast.Expr,
+ value_expr: ^ast.Expr,
flags: bit_set[GlobalFlags],
docs: ^ast.Comment_Group,
comment: ^ast.Comment_Group,
@@ -373,7 +375,7 @@ merge_attributes :: proc(attrs: []^ast.Attribute, foreign_attrs: []^ast.Attribut
// a const variable declaration, so we do a quick check here to distinguish the cases.
is_variable_declaration :: proc(expr: ^ast.Expr) -> bool {
#partial switch v in expr.derived {
- case ^ast.Comp_Lit, ^ast.Basic_Lit, ^ast.Type_Cast, ^ast.Call_Expr:
+ case ^ast.Comp_Lit, ^ast.Basic_Lit, ^ast.Type_Cast, ^ast.Call_Expr, ^ast.Binary_Expr:
return true
case:
return false
@@ -447,10 +449,12 @@ collect_value_decl :: proc(
if len(value_decl.values) > i {
if is_variable_declaration(value_decl.values[i]) {
global_expr.flags += {.Variable}
+ global_expr.value_expr = value_decl.values[i]
}
}
if value_decl.type != nil {
global_expr.expr = value_decl.type
+ global_expr.type_expr = value_decl.type
append(exprs, global_expr)
} else if len(value_decl.values) > i {
global_expr.expr = value_decl.values[i]
diff --git a/src/server/collector.odin b/src/server/collector.odin
index 3b52ca2..607521e 100644
--- a/src/server/collector.odin
+++ b/src/server/collector.odin
@@ -707,6 +707,8 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri
symbol.type = token_type
symbol.doc = get_doc(expr.name_expr, expr.docs, collection.allocator)
symbol.uri = get_index_unique_string(collection, uri)
+ symbol.type_expr = clone_type(expr.type_expr, collection.allocator, &collection.unique_strings)
+ symbol.value_expr = clone_type(expr.value_expr, collection.allocator, &collection.unique_strings)
comment, _ := get_file_comment(file, symbol.range.start.line + 1)
symbol.comment = strings.clone(get_comment(comment), collection.allocator)
diff --git a/src/server/documentation.odin b/src/server/documentation.odin
index 3c75ae3..bc9b12f 100644
--- a/src/server/documentation.odin
+++ b/src/server/documentation.odin
@@ -165,7 +165,7 @@ write_signature :: proc(sb: ^strings.Builder, ast_context: ^AstContext, symbol:
}
if len(v.names) == 0 {
write_indent(sb, depth)
- strings.write_string(sb, "enum {}")
+ strings.write_string(sb, "enum{}")
if symbol.comment != "" {
fmt.sbprintf(sb, " %s", symbol.comment)
}
@@ -220,7 +220,7 @@ write_signature :: proc(sb: ^strings.Builder, ast_context: ^AstContext, symbol:
}
write_where_clauses(sb, v.where_clauses)
if len(v.types) == 0 {
- strings.write_string(sb, " {}")
+ strings.write_string(sb, "{}")
return
}
strings.write_string(sb, " {\n")
@@ -249,6 +249,9 @@ write_signature :: proc(sb: ^strings.Builder, ast_context: ^AstContext, symbol:
strings.write_string(sb, "}")
return
case SymbolProcedureValue:
+ if symbol.type == .Type_Function && depth == 0 {
+ strings.write_string(sb, "#type ")
+ }
write_procedure_symbol_signature(sb, v, detailed_signature = true)
return
case SymbolBitFieldValue:
@@ -332,7 +335,7 @@ write_short_signature :: proc(sb: ^strings.Builder, ast_context: ^AstContext, sy
if len(v.names) > 0 {
strings.write_string(sb, " {..}")
} else {
- strings.write_string(sb, " {}")
+ strings.write_string(sb, "{}")
}
return
case SymbolMapValue:
@@ -342,6 +345,9 @@ write_short_signature :: proc(sb: ^strings.Builder, ast_context: ^AstContext, sy
write_node(sb, ast_context, v.value, "", short_signature = true)
return
case SymbolProcedureValue:
+ if symbol.type == .Type_Function {
+ strings.write_string(sb, "#type ")
+ }
write_procedure_symbol_signature(sb, v, detailed_signature = true)
return
case SymbolAggregateValue, SymbolProcedureGroupValue:
@@ -354,7 +360,7 @@ write_short_signature :: proc(sb: ^strings.Builder, ast_context: ^AstContext, sy
if len(v.types) > 0 {
strings.write_string(sb, " {..}")
} else {
- strings.write_string(sb, " {}")
+ strings.write_string(sb, "{}")
}
return
case SymbolUnionValue:
@@ -364,7 +370,7 @@ write_short_signature :: proc(sb: ^strings.Builder, ast_context: ^AstContext, sy
if len(v.types) > 0 {
strings.write_string(sb, " {..}")
} else {
- strings.write_string(sb, " {}")
+ strings.write_string(sb, "{}")
}
return
case SymbolBitFieldValue:
@@ -430,16 +436,20 @@ write_short_signature :: proc(sb: ^strings.Builder, ast_context: ^AstContext, sy
strings.write_string(sb, "package")
return
case SymbolUntypedValue:
- switch v.type {
- case .Float:
- strings.write_string(sb, "float")
- case .String:
- strings.write_string(sb, "string")
- case .Bool:
- strings.write_string(sb, "bool")
- case .Integer:
- strings.write_string(sb, "int")
+ if .Mutable in symbol.flags || symbol.type == .Field {
+ switch v.type {
+ case .Float:
+ strings.write_string(sb, "float")
+ case .String:
+ strings.write_string(sb, "string")
+ case .Bool:
+ strings.write_string(sb, "bool")
+ case .Integer:
+ strings.write_string(sb, "int")
+ }
+ return
}
+ strings.write_string(sb, v.tok.text)
return
case SymbolGenericValue:
build_string_node(v.expr, sb, false)
@@ -591,36 +601,49 @@ write_struct_hover :: proc(sb: ^strings.Builder, ast_context: ^AstContext, v: Sy
strings.write_string(sb, "struct")
write_poly_list(sb, v.poly, v.poly_names)
+ wrote_tag := false
if v.max_field_align != nil {
strings.write_string(sb, " #max_field_align")
build_string_node(v.max_field_align, sb, false)
+ wrote_tag = true
}
if v.min_field_align != nil {
strings.write_string(sb, " #min_field_align")
build_string_node(v.min_field_align, sb, false)
+ wrote_tag = true
}
if v.align != nil {
strings.write_string(sb, " #align")
build_string_node(v.align, sb, false)
+ wrote_tag = true
}
for tag in v.tags {
switch tag {
case .Is_Raw_Union:
+ wrote_tag = true
strings.write_string(sb, " #raw_union")
case .Is_Packed:
+ wrote_tag = true
strings.write_string(sb, " #packed")
case .Is_No_Copy:
+ wrote_tag = true
strings.write_string(sb, " #no_copy")
}
}
- write_where_clauses(sb, v.where_clauses)
+ if len(v.where_clauses) > 0 {
+ write_where_clauses(sb, v.where_clauses)
+ wrote_tag = true
+ }
if len(v.names) == 0 {
- strings.write_string(sb, " {}")
+ if wrote_tag {
+ strings.write_string(sb, " ")
+ }
+ strings.write_string(sb, "{}")
return
}
@@ -761,6 +784,46 @@ write_node :: proc(
case ^ast.Proc_Type:
symbol = make_symbol_procedure_from_ast(ast_context, nil, n^, name, {}, true, .None, nil)
ok = true
+ case ^ast.Comp_Lit:
+ same_line := true
+ start_line := -1
+ for elem in n.elems {
+ if start_line == -1 {
+ start_line = elem.pos.line
+ } else if start_line != elem.pos.line {
+ same_line = false
+ break
+ }
+ }
+ if same_line {
+ build_string(n, sb, false)
+ } else {
+ build_string(n.type, sb, false)
+ if len(n.elems) == 0 {
+ strings.write_string(sb, "{}")
+ return
+ }
+ if n.type != nil {
+ strings.write_string(sb, " {\n")
+ } else {
+ strings.write_string(sb, "{\n")
+ }
+
+ for elem, i in n.elems {
+ write_indent(sb, depth)
+ if field, ok := elem.derived.(^ast.Field_Value); ok {
+ build_string(field.field, sb, false)
+ strings.write_string(sb, " = ")
+ write_node(sb, ast_context, field.value, "", depth+1, false)
+ } else {
+ build_string(elem, sb, false)
+ }
+ strings.write_string(sb, ",\n")
+ }
+ write_indent(sb, depth-1)
+ strings.write_string(sb, "}")
+ }
+ return
}
if ok {
if short_signature {
@@ -803,6 +866,26 @@ construct_symbol_information :: proc(ast_context: ^AstContext, symbol: Symbol) -
return strings.to_string(sb)
}
+ if symbol.type != .Field && .Mutable not_in symbol.flags {
+ if symbol.value_expr != nil {
+ if symbol.type_expr != nil {
+ strings.write_string(&sb, " : ")
+ build_string_node(symbol.type_expr, &sb, false)
+ strings.write_string(&sb, " : ")
+ write_node(&sb, ast_context, symbol.value_expr, "", 1, false)
+ return strings.to_string(sb)
+ } else if .Variable in symbol.flags {
+ strings.write_string(&sb, " :: ")
+ write_node(&sb, ast_context, symbol.value_expr, "", 1, false)
+ return strings.to_string(sb)
+ }
+ }
+ strings.write_string(&sb, " :: ")
+ } else {
+ strings.write_string(&sb, ": ")
+ }
+
+
if write_symbol_type_information(&sb, ast_context, symbol) {
return strings.to_string(sb)
}
@@ -867,7 +950,6 @@ write_symbol_name :: proc(sb: ^strings.Builder, symbol: Symbol) {
fmt.sbprintf(sb, "%v.", pkg)
}
strings.write_string(sb, symbol.name)
- strings.write_string(sb, ": ")
}
write_symbol_type_information :: proc(sb: ^strings.Builder, ast_context: ^AstContext, symbol: Symbol) -> bool {
diff --git a/src/server/hover.odin b/src/server/hover.odin
index ef4c046..fe69949 100644
--- a/src/server/hover.odin
+++ b/src/server/hover.odin
@@ -344,6 +344,7 @@ get_hover_information :: proc(document: ^Document, position: common.Position) ->
name = selector.name,
pkg = selector.pkg,
signature = get_enum_field_signature(v, i),
+ type = .Field,
}
hover.contents = write_hover_content(&ast_context, symbol)
return hover, true, true
diff --git a/src/server/signature.odin b/src/server/signature.odin
index 619453f..9ffe92b 100644
--- a/src/server/signature.odin
+++ b/src/server/signature.odin
@@ -187,6 +187,7 @@ get_signature_information :: proc(document: ^Document, position: common.Position
get_signature :: proc(symbol: Symbol) -> string {
sb := strings.builder_make()
write_symbol_name(&sb, symbol)
+ strings.write_string(&sb, " :: ")
strings.write_string(&sb, symbol.signature)
return strings.to_string(sb)
}
diff --git a/src/server/symbol.odin b/src/server/symbol.odin
index dac9e7d..4e6b19f 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -225,6 +225,8 @@ Symbol :: struct {
value: SymbolValue,
pointers: int, //how many `^` are applied to the symbol
flags: SymbolFlags,
+ type_expr: ^ast.Expr,
+ value_expr: ^ast.Expr,
}
SymbolType :: enum {