aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/clone.odin292
-rw-r--r--src/server/generics.odin28
-rw-r--r--src/server/symbol.odin9
-rw-r--r--tests/completions_test.odin36
4 files changed, 217 insertions, 148 deletions
diff --git a/src/server/clone.odin b/src/server/clone.odin
index e8cd090..09827d1 100644
--- a/src/server/clone.odin
+++ b/src/server/clone.odin
@@ -1,13 +1,13 @@
package server
-import "core:mem"
import "core:fmt"
-import "core:odin/tokenizer"
-import "core:odin/ast"
-import "core:strings"
-import "core:log"
import "core:intrinsics"
+import "core:log"
+import "core:mem"
+import "core:odin/ast"
+import "core:odin/tokenizer"
import "core:reflect"
+import "core:strings"
_ :: intrinsics
new_type :: proc(
@@ -143,148 +143,150 @@ clone_node :: proc(
}
if res.derived != nil do #partial switch r in res.derived {
- case ^Ident:
- n := node.derived.(^Ident)
+ case ^Ident:
+ n := node.derived.(^Ident)
- if unique_strings == nil {
- r.name = strings.clone(n.name, allocator)
- } else {
- r.name = get_index_unique_string(unique_strings, allocator, n.name)
- }
- case ^Implicit:
- n := node.derived.(^Implicit)
- if unique_strings == nil {
- r.tok.text = strings.clone(n.tok.text, allocator)
- } else {
- r.tok.text = get_index_unique_string(unique_strings, allocator, n.tok.text)
- }
- case ^Undef:
- case ^Basic_Lit:
- n := node.derived.(^Basic_Lit)
- if unique_strings == nil {
- r.tok.text = strings.clone(n.tok.text, allocator)
- } else {
- r.tok.text = get_index_unique_string(unique_strings, allocator, n.tok.text)
- }
- case ^Basic_Directive:
- n := node.derived.(^Basic_Directive)
- if unique_strings == nil {
- r.name = strings.clone(n.name, allocator)
- } else {
- r.name = get_index_unique_string(unique_strings, allocator, n.name)
- }
- case ^Ellipsis:
- r.expr = clone_type(r.expr, allocator, unique_strings)
- case ^Tag_Expr:
- r.expr = clone_type(r.expr, allocator, unique_strings)
- case ^Unary_Expr:
- r.expr = clone_type(r.expr, allocator, unique_strings)
- case ^Binary_Expr:
- n := node.derived.(^Binary_Expr)
- r.left = clone_type(r.left, allocator, unique_strings)
- r.right = clone_type(r.right, allocator, unique_strings)
- //Todo: Replace this with some constant table for opeator text
- if unique_strings == nil {
- r.op.text = strings.clone(n.op.text, allocator)
- } else {
- r.op.text = get_index_unique_string(unique_strings, allocator, n.op.text)
- }
- case ^Paren_Expr:
- r.expr = clone_type(r.expr, allocator, unique_strings)
- case ^Selector_Expr:
- r.expr = clone_type(r.expr, allocator, unique_strings)
- r.field = auto_cast clone_type(r.field, allocator, unique_strings)
- case ^Implicit_Selector_Expr:
- r.field = auto_cast clone_type(r.field, allocator, unique_strings)
- case ^Slice_Expr:
- r.expr = clone_type(r.expr, allocator, unique_strings)
- r.low = clone_type(r.low, allocator, unique_strings)
- r.high = clone_type(r.high, allocator, unique_strings)
- case ^Attribute:
- r.elems = clone_type(r.elems, allocator, unique_strings)
- case ^Distinct_Type:
- r.type = clone_type(r.type, allocator, unique_strings)
- case ^Proc_Type:
- r.params = auto_cast clone_type(r.params, allocator, unique_strings)
- r.results = auto_cast clone_type(r.results, allocator, unique_strings)
- case ^Pointer_Type:
- r.elem = clone_type(r.elem, allocator, unique_strings)
- case ^Array_Type:
- r.len = clone_type(r.len, allocator, unique_strings)
- r.elem = clone_type(r.elem, allocator, unique_strings)
- r.tag = clone_type(r.tag, allocator, unique_strings)
- case ^Dynamic_Array_Type:
- r.elem = clone_type(r.elem, allocator, unique_strings)
- r.tag = clone_type(r.tag, allocator, unique_strings)
- case ^Struct_Type:
- r.poly_params = auto_cast clone_type(r.poly_params, allocator, unique_strings)
- r.align = clone_type(r.align, allocator, unique_strings)
- r.fields = auto_cast clone_type(r.fields, allocator, unique_strings)
- r.where_clauses = clone_type(r.where_clauses, allocator, unique_strings)
- case ^Field:
- r.names = clone_type(r.names, allocator, unique_strings)
- r.type = clone_type(r.type, allocator, unique_strings)
- r.default_value = clone_type(r.default_value, allocator, unique_strings)
- case ^Field_List:
- r.list = clone_type(r.list, allocator, unique_strings)
- case ^Field_Value:
- r.field = clone_type(r.field, allocator, unique_strings)
- r.value = clone_type(r.value, allocator, unique_strings)
- case ^Union_Type:
- r.poly_params = auto_cast clone_type(r.poly_params, allocator, unique_strings)
- r.align = clone_type(r.align, allocator, unique_strings)
- r.variants = clone_type(r.variants, allocator, unique_strings)
- r.where_clauses = clone_type(r.where_clauses, allocator, unique_strings)
- case ^Enum_Type:
- r.base_type = clone_type(r.base_type, allocator, unique_strings)
- r.fields = clone_type(r.fields, allocator, unique_strings)
- case ^Bit_Set_Type:
- r.elem = clone_type(r.elem, allocator, unique_strings)
- r.underlying = clone_type(r.underlying, allocator, unique_strings)
- case ^Map_Type:
- r.key = clone_type(r.key, allocator, unique_strings)
- r.value = clone_type(r.value, allocator, unique_strings)
- case ^Call_Expr:
- r.expr = clone_type(r.expr, allocator, unique_strings)
- r.args = clone_type(r.args, allocator, unique_strings)
- case ^Typeid_Type:
- r.specialization = clone_type(r.specialization, allocator, unique_strings)
- case ^Ternary_When_Expr:
- r.x = clone_type(r.x, allocator, unique_strings)
- r.cond = clone_type(r.cond, allocator, unique_strings)
- r.y = clone_type(r.y, allocator, unique_strings)
- case ^Poly_Type:
- r.type = auto_cast clone_type(r.type, allocator, unique_strings)
- r.specialization = clone_type(r.specialization, allocator, unique_strings)
- case ^Proc_Group:
- r.args = clone_type(r.args, allocator, unique_strings)
- case ^Comp_Lit:
- r.type = clone_type(r.type, allocator, unique_strings)
- r.elems = clone_type(r.elems, allocator, unique_strings)
- case ^Proc_Lit:
- r.type = cast(^Proc_Type)clone_type(cast(^Node)r.type, allocator, unique_strings)
- r.body = nil
- r.where_clauses = nil
- case ^Helper_Type:
- r.type = clone_type(r.type, allocator, unique_strings)
- case ^Type_Cast:
- r.type = clone_type(r.type, allocator, unique_strings)
- r.expr = clone_type(r.expr, allocator, unique_strings)
- case ^Deref_Expr:
- r.expr = clone_type(r.expr, allocator, unique_strings)
- case ^Index_Expr:
- r.expr = clone_type(r.expr, allocator, unique_strings)
- r.index = clone_type(r.index, allocator, unique_strings)
- case ^Multi_Pointer_Type:
- r.elem = clone_type(r.elem, allocator, unique_strings)
- case ^Matrix_Type:
- r.elem = clone_type(r.elem, allocator, unique_strings)
- case ^Type_Assertion:
- r.expr = clone_type(r.expr, allocator, unique_strings)
- r.type = clone_type(r.type, allocator, unique_strings)
- case:
- //fmt.logf("Unhandled node kind: %T", r)
+ if unique_strings == nil {
+ r.name = strings.clone(n.name, allocator)
+ } else {
+ r.name = get_index_unique_string(unique_strings, allocator, n.name)
+ }
+ case ^Implicit:
+ n := node.derived.(^Implicit)
+ if unique_strings == nil {
+ r.tok.text = strings.clone(n.tok.text, allocator)
+ } else {
+ r.tok.text = get_index_unique_string(unique_strings, allocator, n.tok.text)
+ }
+ case ^Undef:
+ case ^Basic_Lit:
+ n := node.derived.(^Basic_Lit)
+ if unique_strings == nil {
+ r.tok.text = strings.clone(n.tok.text, allocator)
+ } else {
+ r.tok.text = get_index_unique_string(unique_strings, allocator, n.tok.text)
}
+ case ^Basic_Directive:
+ n := node.derived.(^Basic_Directive)
+ if unique_strings == nil {
+ r.name = strings.clone(n.name, allocator)
+ } else {
+ r.name = get_index_unique_string(unique_strings, allocator, n.name)
+ }
+ case ^Ellipsis:
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ case ^Tag_Expr:
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ case ^Unary_Expr:
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ case ^Binary_Expr:
+ n := node.derived.(^Binary_Expr)
+ r.left = clone_type(r.left, allocator, unique_strings)
+ r.right = clone_type(r.right, allocator, unique_strings)
+ //Todo: Replace this with some constant table for opeator text
+ if unique_strings == nil {
+ r.op.text = strings.clone(n.op.text, allocator)
+ } else {
+ r.op.text = get_index_unique_string(unique_strings, allocator, n.op.text)
+ }
+ case ^Paren_Expr:
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ case ^Selector_Expr:
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ r.field = auto_cast clone_type(r.field, allocator, unique_strings)
+ case ^Implicit_Selector_Expr:
+ r.field = auto_cast clone_type(r.field, allocator, unique_strings)
+ case ^Slice_Expr:
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ r.low = clone_type(r.low, allocator, unique_strings)
+ r.high = clone_type(r.high, allocator, unique_strings)
+ case ^Attribute:
+ r.elems = clone_type(r.elems, allocator, unique_strings)
+ case ^Distinct_Type:
+ r.type = clone_type(r.type, allocator, unique_strings)
+ case ^Proc_Type:
+ r.params = auto_cast clone_type(r.params, allocator, unique_strings)
+ r.results = auto_cast clone_type(r.results, allocator, unique_strings)
+ case ^Pointer_Type:
+ r.elem = clone_type(r.elem, allocator, unique_strings)
+ case ^Array_Type:
+ r.len = clone_type(r.len, allocator, unique_strings)
+ r.elem = clone_type(r.elem, allocator, unique_strings)
+ r.tag = clone_type(r.tag, allocator, unique_strings)
+ case ^Dynamic_Array_Type:
+ r.elem = clone_type(r.elem, allocator, unique_strings)
+ r.tag = clone_type(r.tag, allocator, unique_strings)
+ case ^Struct_Type:
+ r.poly_params = auto_cast clone_type(r.poly_params, allocator, unique_strings)
+ r.align = clone_type(r.align, allocator, unique_strings)
+ r.fields = auto_cast clone_type(r.fields, allocator, unique_strings)
+ r.where_clauses = clone_type(r.where_clauses, allocator, unique_strings)
+ case ^Field:
+ r.names = clone_type(r.names, allocator, unique_strings)
+ r.type = clone_type(r.type, allocator, unique_strings)
+ r.default_value = clone_type(r.default_value, allocator, unique_strings)
+ case ^Field_List:
+ r.list = clone_type(r.list, allocator, unique_strings)
+ case ^Field_Value:
+ r.field = clone_type(r.field, allocator, unique_strings)
+ r.value = clone_type(r.value, allocator, unique_strings)
+ case ^Union_Type:
+ r.poly_params = auto_cast clone_type(r.poly_params, allocator, unique_strings)
+ r.align = clone_type(r.align, allocator, unique_strings)
+ r.variants = clone_type(r.variants, allocator, unique_strings)
+ r.where_clauses = clone_type(r.where_clauses, allocator, unique_strings)
+ case ^Enum_Type:
+ r.base_type = clone_type(r.base_type, allocator, unique_strings)
+ r.fields = clone_type(r.fields, allocator, unique_strings)
+ case ^Bit_Set_Type:
+ r.elem = clone_type(r.elem, allocator, unique_strings)
+ r.underlying = clone_type(r.underlying, allocator, unique_strings)
+ case ^Map_Type:
+ r.key = clone_type(r.key, allocator, unique_strings)
+ r.value = clone_type(r.value, allocator, unique_strings)
+ case ^Call_Expr:
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ r.args = clone_type(r.args, allocator, unique_strings)
+ case ^Typeid_Type:
+ r.specialization = clone_type(r.specialization, allocator, unique_strings)
+ case ^Ternary_When_Expr:
+ r.x = clone_type(r.x, allocator, unique_strings)
+ r.cond = clone_type(r.cond, allocator, unique_strings)
+ r.y = clone_type(r.y, allocator, unique_strings)
+ case ^Poly_Type:
+ r.type = auto_cast clone_type(r.type, allocator, unique_strings)
+ r.specialization = clone_type(r.specialization, allocator, unique_strings)
+ case ^Proc_Group:
+ r.args = clone_type(r.args, allocator, unique_strings)
+ case ^Comp_Lit:
+ r.type = clone_type(r.type, allocator, unique_strings)
+ r.elems = clone_type(r.elems, allocator, unique_strings)
+ case ^Proc_Lit:
+ r.type = cast(^Proc_Type)clone_type(cast(^Node)r.type, allocator, unique_strings)
+ r.body = nil
+ r.where_clauses = nil
+ case ^Helper_Type:
+ r.type = clone_type(r.type, allocator, unique_strings)
+ case ^Type_Cast:
+ r.type = clone_type(r.type, allocator, unique_strings)
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ case ^Deref_Expr:
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ case ^Index_Expr:
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ r.index = clone_type(r.index, allocator, unique_strings)
+ case ^Multi_Pointer_Type:
+ r.elem = clone_type(r.elem, allocator, unique_strings)
+ case ^Matrix_Type:
+ r.elem = clone_type(r.elem, allocator, unique_strings)
+ r.column_count = clone_type(r.column_count, allocator, unique_strings)
+ r.row_count = clone_type(r.row_count, allocator, unique_strings)
+ case ^Type_Assertion:
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ r.type = clone_type(r.type, allocator, unique_strings)
+ case:
+ //fmt.logf("Unhandled node kind: %T", r)
+ }
return res
}
diff --git a/src/server/generics.odin b/src/server/generics.odin
index b4393bb..5921de2 100644
--- a/src/server/generics.odin
+++ b/src/server/generics.odin
@@ -54,6 +54,10 @@ resolve_poly :: proc(
}
}
return true
+ } else if type != nil {
+ if ident, ok := unwrap_ident(type); ok {
+ poly_map[ident.name] = specialization
+ }
}
#partial switch p in specialization.derived {
@@ -281,6 +285,11 @@ find_and_replace_poly_type :: proc(
return v, ok
}
}
+ if poly, ok := node.derived.(^ast.Poly_Type); ok && poly.type != nil {
+ if v, ok := poly_map[poly.type.name]; ok {
+ return v, ok
+ }
+ }
return nil, false
}
@@ -296,6 +305,16 @@ find_and_replace_poly_type :: proc(
poly_map := cast(^map[string]^ast.Expr)visitor.data
#partial switch v in node.derived {
+ case ^ast.Matrix_Type:
+ if expr, ok := is_in_poly_map(v.elem, poly_map); ok {
+ v.elem = expr
+ }
+ if expr, ok := is_in_poly_map(v.column_count, poly_map); ok {
+ v.column_count = expr
+ }
+ if expr, ok := is_in_poly_map(v.row_count, poly_map); ok {
+ v.row_count = expr
+ }
case ^ast.Dynamic_Array_Type:
if expr, ok := is_in_poly_map(v.elem, poly_map); ok {
v.elem = expr
@@ -417,7 +436,7 @@ resolve_generic_function_symbol :: proc(
)
if symbol_expr == nil {
- continue
+ return {}, false
}
if resolve_poly(
@@ -428,7 +447,11 @@ resolve_generic_function_symbol :: proc(
&poly_map,
) {
if poly, ok := name.derived.(^ast.Poly_Type); ok {
- poly_map[poly.type.name] = call_expr.args[i]
+ poly_map[poly.type.name] = clone_expr(
+ call_expr.args[i],
+ ast_context.allocator,
+ nil,
+ )
}
}
}
@@ -438,6 +461,7 @@ resolve_generic_function_symbol :: proc(
}
for k, v in poly_map {
+ find_and_replace_poly_type(v, &poly_map)
//fmt.println(k, v.derived, "\n")
}
diff --git a/src/server/symbol.odin b/src/server/symbol.odin
index 0f86d5c..bfd4af0 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -339,8 +339,15 @@ symbol_to_expr :: proc(
type.column_count = v.y
type.elem = v.expr
return type
+ case SymbolProcedureValue:
+ type := new_type(ast.Proc_Type, pos, end, allocator)
+ type.results = new_type(ast.Field_List, pos, end, allocator)
+ type.results.list = v.return_types
+ type.params = new_type(ast.Field_List, pos, end, allocator)
+ type.params.list = v.arg_types
+ return type
case:
- log.errorf("Unhandled symbol %v", symbol)
+ log.panicf("Unhandled symbol %v", symbol)
}
return nil
diff --git a/tests/completions_test.odin b/tests/completions_test.odin
index 3553461..e5a9460 100644
--- a/tests/completions_test.odin
+++ b/tests/completions_test.odin
@@ -2572,3 +2572,39 @@ ast_poly_proc_matrix_constant_array_2 :: proc(t: ^testing.T) {
test.expect_completion_details(t, &source, "", {"test.myss: [10]f32"})
}
+
+@(test)
+ast_poly_proc_matrix_whole :: proc(t: ^testing.T) {
+ packages := make([dynamic]test.Package)
+
+ source := test.Source {
+ main = `package test
+
+ @(require_results)
+ matrix_mul :: proc "contextless" (
+ a, b: $M/matrix[$N, N]$E,
+ ) -> (
+ c: M,
+ ) where !IS_ARRAY(E),
+ IS_NUMERIC(E) #no_bounds_check {
+ return a * b
+ }
+
+ matrix4_from_trs_f16 :: proc "contextless" () -> matrix[4, 4]f32 {
+ translation: matrix[4, 4]f32
+ rotation: matrix[4, 4]f32
+ dsszz := matrix_mul(scale, translation)
+ dssz{*}
+ }
+ `,
+ packages = {},
+ }
+
+ test.expect_completion_details(
+ t,
+ &source,
+ "",
+ {"test.dsszz: matrix[4,4]f32"},
+ )
+
+}