aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Gavin <danielgavin5@hotmail.com>2022-04-15 19:56:20 +0200
committerDaniel Gavin <danielgavin5@hotmail.com>2022-04-15 19:56:20 +0200
commit1ff3cccc05724f1a2485edbbace6ac540c4cb485 (patch)
treef72ff54ba467041a0c2db247d46efc53eeb37f2c /src
parentb4720f71d63f08ec6a734fb79fb0816756484ac6 (diff)
Add proper multi_pointer support and fix range half range op
Diffstat (limited to 'src')
-rw-r--r--src/common/ast.odin4
-rw-r--r--src/server/analysis.odin61
-rw-r--r--src/server/collector.odin42
-rw-r--r--src/server/definition.odin2
-rw-r--r--src/server/rename.odin3
-rw-r--r--src/server/requests.odin3
-rw-r--r--src/server/semantic_tokens.odin3
-rw-r--r--src/server/symbol.odin7
-rw-r--r--src/testing/testing.odin2
9 files changed, 108 insertions, 19 deletions
diff --git a/src/common/ast.odin b/src/common/ast.odin
index c8398ae..841c519 100644
--- a/src/common/ast.odin
+++ b/src/common/ast.odin
@@ -637,6 +637,10 @@ node_equal_node :: proc(a, b: ^ast.Node) -> bool {
if n, ok := a.derived.(^Dynamic_Array_Type); ok {
return node_equal(n.elem, m.elem)
}
+ case ^ast.Multi_Pointer_Type:
+ if n, ok := a.derived.(^Multi_Pointer_Type); ok {
+ return node_equal(n.elem, m.elem)
+ }
case ^Struct_Type:
if n, ok := a.derived.(^Struct_Type); ok {
ret := node_equal(n.poly_params, m.poly_params)
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 7ad405b..8979fe1 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -597,6 +597,26 @@ is_symbol_same_typed :: proc(ast_context: ^AstContext, a, b: Symbol, flags: ast.
}
return is_symbol_same_typed(ast_context, a_symbol, b_symbol)
+ case SymbolMultiPointer:
+ b_value := b.value.(SymbolMultiPointer)
+
+ a_symbol: Symbol
+ b_symbol: Symbol
+ ok: bool
+
+ a_symbol, ok = resolve_type_expression(ast_context, a_value.expr)
+
+ if !ok {
+ return false
+ }
+
+ b_symbol, ok = resolve_type_expression(ast_context, b_value.expr)
+
+ if !ok {
+ return false
+ }
+
+ return is_symbol_same_typed(ast_context, a_symbol, b_symbol)
case SymbolDynamicArrayValue:
b_value := b.value.(SymbolDynamicArrayValue)
@@ -854,6 +874,8 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (S
return make_symbol_array_from_ast(ast_context, v^, ast_context.field_name), true
case ^Dynamic_Array_Type:
return make_symbol_dynamic_array_from_ast(ast_context, v^, ast_context.field_name), true
+ case ^Multi_Pointer_Type:
+ return make_symbol_multi_pointer_from_ast(ast_context, v^, ast_context.field_name), true
case ^Map_Type:
return make_symbol_map_from_ast(ast_context, v^, ast_context.field_name), true
case ^Proc_Type:
@@ -923,10 +945,6 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (S
symbol, ok := resolve_type_expression(ast_context, v.elem)
symbol.pointers += 1
return symbol, ok
- case ^Multi_Pointer_Type:
- symbol, ok := resolve_type_expression(ast_context, v.elem)
- symbol.pointers += 1
- return symbol, ok
case ^Index_Expr:
indexed, ok := resolve_type_expression(ast_context, v.expr)
@@ -945,6 +963,8 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (S
symbol, ok = resolve_type_expression(ast_context, v2.expr)
case SymbolMapValue:
symbol, ok = resolve_type_expression(ast_context, v2.value)
+ case SymbolMultiPointer:
+ symbol, ok = resolve_type_expression(ast_context, v2.expr)
}
symbol.type = indexed.type
@@ -1469,6 +1489,9 @@ resolve_symbol_return :: proc(ast_context: ^AstContext, symbol: Symbol, ok := tr
}
case SymbolGenericValue:
ret, ok := resolve_type_expression(ast_context, v.expr)
+ if symbol.type == .Variable {
+ ret.type = symbol.type
+ }
return ret, ok
}
@@ -1702,6 +1725,21 @@ make_symbol_dynamic_array_from_ast :: proc(ast_context: ^AstContext, v: ast.Dyna
return symbol
}
+make_symbol_multi_pointer_from_ast :: proc(ast_context: ^AstContext, v: ast.Multi_Pointer_Type, name: string) -> Symbol {
+ symbol := Symbol {
+ range = common.get_token_range(v.node, ast_context.file.src),
+ type = .Variable,
+ pkg = get_package_from_node(v.node),
+ name = name,
+ }
+
+ symbol.value = SymbolMultiPointer {
+ expr = v.elem,
+ }
+
+ return symbol
+}
+
make_symbol_map_from_ast :: proc(ast_context: ^AstContext, v: ast.Map_Type, name: string) -> Symbol {
symbol := Symbol {
range = common.get_token_range(v.node, ast_context.file.src),
@@ -2208,7 +2246,16 @@ get_locals_for_range_stmt :: proc(file: ast.File, stmt: ast.Range_Stmt, ast_cont
if stmt.expr == nil {
return
}
-
+
+ if binary, ok := stmt.expr.derived.(^ast.Binary_Expr); ok {
+ if binary.op.kind == .Range_Half {
+ if ident, ok := stmt.vals[0].derived.(^Ident); ok {
+ store_local(ast_context, make_int_ast(ast_context), ident.pos.offset, ident.name, ast_context.local_id)
+ ast_context.variables[ident.name] = true
+ }
+ }
+ }
+
if symbol, ok := resolve_type_expression(ast_context, stmt.expr); ok {
#partial switch v in symbol.value {
case SymbolMapValue:
@@ -2626,6 +2673,8 @@ get_signature :: proc(ast_context: ^AstContext, ident: ast.Ident, symbol: Symbol
else {
return "union"
}
+ case SymbolMultiPointer:
+ return strings.concatenate(a = {"[^]", common.node_to_string(v.expr)}, allocator = ast_context.allocator)
case SymbolDynamicArrayValue:
return strings.concatenate(a = {"[dynamic]", common.node_to_string(v.expr)}, allocator = ast_context.allocator)
case SymbolSliceValue:
@@ -3358,6 +3407,8 @@ get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentP
get_document_position(n.elem, position_context)
case ^Dynamic_Array_Type:
get_document_position(n.elem, position_context)
+ case ^Multi_Pointer_Type:
+ get_document_position(n.elem, position_context)
case ^Struct_Type:
get_document_position(n.poly_params, position_context)
get_document_position(n.align, position_context)
diff --git a/src/server/collector.odin b/src/server/collector.odin
index cf7e629..2de0068 100644
--- a/src/server/collector.odin
+++ b/src/server/collector.odin
@@ -231,6 +231,16 @@ collect_dynamic_array :: proc(collection: ^SymbolCollection, array: ast.Dynamic_
}
}
+collect_multi_pointer :: proc(collection: ^SymbolCollection, array: ast.Multi_Pointer_Type, package_map: map[string]string) -> SymbolMultiPointer {
+ elem := clone_type(array.elem, collection.allocator, &collection.unique_strings)
+
+ replace_package_alias(elem, package_map, collection)
+
+ return SymbolMultiPointer {
+ expr = elem,
+ }
+}
+
collect_generic :: proc(collection: ^SymbolCollection, expr: ^ast.Expr, package_map: map[string]string, uri: string) -> SymbolGenericValue {
//Bit hacky right now, but it's hopefully a temporary solution.
//In the c package code it uses a documentation package(builtin).
@@ -346,6 +356,10 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri
token = v^
token_type = .Variable
symbol.value = collect_dynamic_array(collection, v^, package_map)
+ case ^ast.Multi_Pointer_Type:
+ token = v^
+ token_type = .Variable
+ symbol.value = collect_multi_pointer(collection, v^, package_map)
case ^ast.Basic_Lit:
token = v^
symbol.value = collect_generic(collection, col_expr, package_map, uri)
@@ -445,16 +459,26 @@ collect_references :: proc(collection: ^SymbolCollection, file: ast.File, uri: s
parse_imports(&document, &common.config)
symbols_and_nodes := resolve_entire_file(&document, common.scratch_allocator(document.allocator))
-
+
for k, v in symbols_and_nodes {
- if pkg, ok := &collection.references[v.symbol.pkg]; ok {
- if ref, ok := &pkg[v.symbol.name]; ok {
- if ident, ok := v.node.derived.(^ast.Ident); ok {
- //append(&ref.identifiers, cast(^ast.Ident)clone_type(ident, collection.allocator, nil))
- } else if selector, ok := v.node.derived.(^ast.Selector_Expr); ok {
- //append(&ref.selectors, cast(^ast.Selector_Expr)clone_type(selector, collection.allocator, nil))
- }
- }
+ pkg: ^map[string]Reference
+
+ if pkg, ok = &collection.references[v.symbol.pkg]; !ok {
+ collection.references[get_index_unique_string(collection, v.symbol.pkg)] = make(map[string]Reference, 100, collection.allocator)
+ pkg = &collection.references[v.symbol.pkg]
+ }
+
+ ref: ^Reference
+
+ if ref, ok := &pkg[v.symbol.name]; !ok {
+ pkg[get_index_unique_string(collection, v.symbol.name)] = {}
+ ref = &pkg[v.symbol.name]
+ }
+
+ if ident, ok := v.node.derived.(^ast.Ident); ok {
+ append(&ref.identifiers, cast(^ast.Ident)clone_type(ident, collection.allocator, nil))
+ } else if selector, ok := v.node.derived.(^ast.Selector_Expr); ok {
+ append(&ref.selectors, cast(^ast.Selector_Expr)clone_type(selector, collection.allocator, nil))
}
}
diff --git a/src/server/definition.odin b/src/server/definition.odin
index 4447bb2..3bcdcb3 100644
--- a/src/server/definition.odin
+++ b/src/server/definition.odin
@@ -79,7 +79,6 @@ get_definition_location :: proc(document: ^common.Document, position: common.Pos
field: string
if position_context.field != nil {
-
#partial switch v in position_context.field.derived {
case ^ast.Ident:
field = v.name
@@ -110,7 +109,6 @@ get_definition_location :: proc(document: ^common.Document, position: common.Pos
return {}, false
}
} else if position_context.identifier != nil {
-
if resolved, ok := resolve_location_identifier(&ast_context, position_context.identifier.derived.(^ast.Ident)^); ok {
location.range = resolved.range
uri = resolved.uri
diff --git a/src/server/rename.odin b/src/server/rename.odin
index 7c4629e..16becbc 100644
--- a/src/server/rename.odin
+++ b/src/server/rename.odin
@@ -12,6 +12,8 @@ get_rename :: proc(document: ^common.Document, new_text: string, position: commo
edits := make([dynamic]TextEdit, context.temp_allocator)
+
+ /*
symbol_and_nodes := resolve_entire_file(document)
ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri)
@@ -63,6 +65,7 @@ get_rename :: proc(document: ^common.Document, new_text: string, position: commo
append(&document_changes, document_change)
workspace.documentChanges = document_changes[:]
+ */
return workspace, true
} \ No newline at end of file
diff --git a/src/server/requests.odin b/src/server/requests.odin
index fdc5d31..3aaff45 100644
--- a/src/server/requests.odin
+++ b/src/server/requests.odin
@@ -453,7 +453,6 @@ request_initialize :: proc (params: json.Value, id: RequestId, config: ^common.C
config.collections["vendor"] = path.join(elems = {forward_path, "vendor"}, allocator = context.allocator)
}
-
for format in initialize_params.capabilities.textDocument.hover.contentFormat {
if format == "markdown" {
config.hover_support_md = true
@@ -502,7 +501,7 @@ request_initialize :: proc (params: json.Value, id: RequestId, config: ^common.C
includeText = true,
},
},
- renameProvider = false,
+ renameProvider = true,
definitionProvider = true,
completionProvider = CompletionOptions {
resolveProvider = false,
diff --git a/src/server/semantic_tokens.odin b/src/server/semantic_tokens.odin
index acbe1a5..e373a36 100644
--- a/src/server/semantic_tokens.odin
+++ b/src/server/semantic_tokens.odin
@@ -306,6 +306,9 @@ visit_node :: proc(node: ^ast.Node, builder: ^SemanticTokenBuilder, ast_context:
case ^Dynamic_Array_Type:
write_semantic_string(builder, n.dynamic_pos, "dynamic", ast_context.file.src, .Keyword, .None)
visit(n.elem, builder, ast_context)
+ case ^Multi_Pointer_Type:
+ write_semantic_string(builder, n.pos, "[^]", ast_context.file.src, .Keyword, .None)
+ visit(n.elem, builder, ast_context)
case ^Field_Value:
if ident, ok := n.field.derived.(^Ident); ok {
write_semantic_node(builder, n.field, ast_context.file.src, .Property, .None)
diff --git a/src/server/symbol.odin b/src/server/symbol.odin
index b6a3a3c..791c609 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -52,6 +52,10 @@ SymbolDynamicArrayValue :: struct {
expr: ^ast.Expr,
}
+SymbolMultiPointer :: struct {
+ expr: ^ast.Expr,
+}
+
SymbolFixedArrayValue :: struct {
len: ^ast.Expr,
expr: ^ast.Expr,
@@ -97,6 +101,7 @@ SymbolValue :: union {
SymbolAggregateValue,
SymbolDynamicArrayValue,
SymbolFixedArrayValue,
+ SymbolMultiPointer,
SymbolMapValue,
SymbolSliceValue,
SymbolBasicValue,
@@ -160,6 +165,8 @@ free_symbol :: proc(symbol: Symbol, allocator: mem.Allocator) {
}
switch v in symbol.value {
+ case SymbolMultiPointer:
+ common.free_ast(v.expr, allocator)
case SymbolProcedureValue:
common.free_ast(v.return_types, allocator)
common.free_ast(v.arg_types, allocator)
diff --git a/src/testing/testing.odin b/src/testing/testing.odin
index 356c457..a824d87 100644
--- a/src/testing/testing.odin
+++ b/src/testing/testing.odin
@@ -36,7 +36,7 @@ setup :: proc(src: ^Source) {
src.document.allocator = new(common.Scratch_Allocator);
src.document.package_name = "test";
- common.scratch_allocator_init(src.document.allocator, mem.kilobytes(200), context.temp_allocator);
+ common.scratch_allocator_init(src.document.allocator, mem.Kilobyte * 200, context.temp_allocator);
//no unicode in tests currently
current, last: u8;