From c8a2467facd17a1f780a356299343b2a1319762f Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Mon, 1 Mar 2021 22:18:38 +0100 Subject: [PATCH] Compiles without errors. Still needs improvement --- src/analysis.zig | 292 ++++++++++++++++++++++++++------------------- src/main.zig | 2 +- src/offsets.zig | 4 +- src/references.zig | 19 ++- 4 files changed, 181 insertions(+), 136 deletions(-) diff --git a/src/analysis.zig b/src/analysis.zig index 92dc92d..1f3980b 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -1055,13 +1055,12 @@ pub fn collectImports(import_arr: *std.ArrayList([]const u8), tree: ast.Tree) !v const init_node_tag = tags[init_node]; switch (init_node_tag) { .builtin_call => try maybeCollectImport(tree, init_node, import_arr), - // @TODO: FIX ME what is the syntax to support for imports using dot notation? - // .Period => { - // const infix_op = init_node.cast(ast.Node.SimpleInfixOp).?; - - // if (infix_op.lhs.tag != .BuiltinCall) continue; - // try maybeCollectImport(tree, infix_op.lhs.castTag(.BuiltinCall).?, import_arr); - // }, + .field_access => { + const lhs = tree.nodes.items(.data)[init_node].lhs; + if (isBuiltinCall(tree, lhs)) { + try maybeCollectImport(tree, lhs, import_arr); + } + }, else => {}, } } @@ -1268,7 +1267,7 @@ fn isBuiltinCall(tree: ast.Tree, node: ast.Node.Index) bool { }; } -fn builtinCallParams(tree: ast.Tree, node: ast.Node.Index) []const ast.Node.Index { +pub fn builtinCallParams(tree: ast.Tree, node: ast.Node.Index) []const ast.Node.Index { std.debug.assert(isBuiltinCall(tree, node)); const datas = tree.nodes.items(.data); @@ -1290,7 +1289,7 @@ pub fn fnProto(tree: ast.Tree, node: ast.Node.Index, buf: *[1]ast.Node.Index) ?a .fn_proto_multi => tree.fnProtoMulti(node), .fn_proto_one => tree.fnProtoOne(buf, node), .fn_proto_simple => tree.fnProtoSimple(buf, node), - .fn_decl => tree.fnProto(tree.nodes.items(.data)[node].lhs), + // .fn_decl => tree.fnProto(tree.nodes.items(.data)[node].lhs), else => null, }; } @@ -1479,107 +1478,147 @@ pub fn documentPositionContext(arena: *std.heap.ArenaAllocator, document: types. }; } -fn addOutlineNodes(allocator: *std.mem.Allocator, tree: ast.Tree, parent: ast.Node.Index, context: *GetDocumentSymbolsContext) anyerror!void { - switch (tree.nodes.items(.tag)[parent]) { - .StringLiteral, - .IntegerLiteral, - .BuiltinCall, - .Call, - .Identifier, - .Add, - .AddWrap, - .ArrayCat, - .ArrayMult, - .Assign, - .AssignBitAnd, - .AssignBitOr, - .AssignBitShiftLeft, - .AssignBitShiftRight, - .AssignBitXor, - .AssignDiv, - .AssignSub, - .AssignSubWrap, - .AssignMod, - .AssignAdd, - .AssignAddWrap, - .AssignMul, - .AssignMulWrap, - .BangEqual, - .BitAnd, - .BitOr, - .BitShiftLeft, - .BitShiftRight, - .BitXor, - .BoolAnd, - .BoolOr, - .Div, - .EqualEqual, - .ErrorUnion, - .GreaterOrEqual, - .GreaterThan, - .LessOrEqual, - .LessThan, - .MergeErrorSets, - .Mod, - .Mul, - .MulWrap, - .Period, - .Range, - .Sub, - .SubWrap, - .OrElse, - .AddressOf, - .Await, - .BitNot, - .BoolNot, - .OptionalType, - .Negation, - .NegationWrap, - .Resume, - .Try, - .ArrayType, - .ArrayTypeSentinel, - .PtrType, - .SliceType, - .Slice, - .Deref, - .UnwrapOptional, - .ArrayAccess, - .Return, - .Break, - .Continue, - .ArrayInitializerDot, - .SwitchElse, - .SwitchCase, - .For, - .EnumLiteral, - .PointerIndexPayload, - .StructInitializerDot, - .PointerPayload, - .While, - .Switch, - .Else, - .BoolLiteral, - .NullLiteral, - .Defer, - .StructInitializer, - .FieldInitializer, - .If, - .MultilineStringLiteral, - .UndefinedLiteral, - .AnyType, - .Block, - .ErrorSetDecl, +fn addOutlineNodes(allocator: *std.mem.Allocator, tree: ast.Tree, child: ast.Node.Index, context: *GetDocumentSymbolsContext) anyerror!void { + switch (tree.nodes.items(.tag)[child]) { + .string_literal, + .integer_literal, + .builtin_call, + .builtin_call_comma, + .builtin_call_two, + .builtin_call_two_comma, + .call, + .call_comma, + .call_one, + .call_one_comma, + .async_call, + .async_call_comma, + .async_call_one, + .async_call_one_comma, + .identifier, + .add, + .add_wrap, + .array_cat, + .array_mult, + .assign, + .assign_bit_and, + .assign_bit_or, + .assign_bit_shift_left, + .assign_bit_shift_right, + .assign_bit_xor, + .assign_div, + .assign_sub, + .assign_sub_wrap, + .assign_mod, + .assign_add, + .assign_add_wrap, + .assign_mul, + .assign_mul_wrap, + .bang_equal, + .bit_and, + .bit_or, + .bit_shift_left, + .bit_shift_right, + .bit_xor, + .bool_and, + .bool_or, + .div, + .equal_equal, + .error_union, + .greater_or_equal, + .greater_than, + .less_or_equal, + .less_than, + .merge_error_sets, + .mod, + .mul, + .mul_wrap, + .field_access, + .switch_range, + .sub, + .sub_wrap, + .@"orelse", + .address_of, + .@"await", + .bit_not, + .bool_not, + .optional_type, + .negation, + .negation_wrap, + .@"resume", + .@"try", + .array_type, + .array_type_sentinel, + .ptr_type, + .ptr_type_aligned, + .ptr_type_bit_range, + .ptr_type_sentinel, + .slice_open, + .slice_sentinel, + .deref, + .unwrap_optional, + .array_access, + .@"return", + .@"break", + .@"continue", + .array_init, + .array_init_comma, + .array_init_dot, + .array_init_dot_comma, + .array_init_dot_two, + .array_init_dot_two_comma, + .array_init_one, + .array_init_one_comma, + .@"switch", + .switch_comma, + .switch_case, + .switch_case_one, + .@"for", + .for_simple, + .enum_literal, + .struct_init, + .struct_init_comma, + .struct_init_dot, + .struct_init_dot_comma, + .struct_init_dot_two, + .struct_init_dot_two_comma, + .struct_init_one, + .struct_init_one_comma, + .@"while", + .while_simple, + .while_cont, + .true_literal, + .false_literal, + .null_literal, + .@"defer", + .@"if", + .if_simple, + .multiline_string_literal, + .undefined_literal, + .@"anytype", + .block, + .block_semicolon, + .block_two, + .block_two_semicolon, + .error_set_decl, => return, - - .ContainerDecl => { - const decl = child.castTag(.ContainerDecl).?; - - for (decl.fieldsAndDecls()) |cchild| - try addOutlineNodes(allocator, tree, cchild, context); + .container_decl, + .container_decl_arg, + .container_decl_arg_trailing, + .container_decl_two, + .container_decl_two_trailing, + .tagged_union, + .tagged_union_trailing, + .tagged_union_enum_tag, + .tagged_union_enum_tag_trailing, + .tagged_union_two, + .tagged_union_two_trailing, + => { + var buf: [2]ast.Node.Index = undefined; + for (declMembers(tree, tree.nodes.items(.tag)[child], child, &buf)) |member| + try addOutlineNodes(allocator, tree, member, context); return; }, - else => {}, + else => |t| {}, } try getDocumentSymbolsInternal(allocator, tree, child, context); } @@ -1614,6 +1653,7 @@ fn getDocumentSymbolsInternal(allocator: *std.mem.Allocator, tree: ast.Tree, nod }; const tags = tree.nodes.items(.tag); + log.debug("{s} - {s}", .{ name, tags[node] }); (try context.symbols.addOne()).* = .{ .name = name, .kind = switch (tags[node]) { @@ -1621,6 +1661,7 @@ fn getDocumentSymbolsInternal(allocator: *std.mem.Allocator, tree: ast.Tree, nod .fn_proto_simple, .fn_proto_multi, .fn_proto_one, + .fn_decl, => .Function, .local_var_decl, .global_var_decl, @@ -1632,6 +1673,10 @@ fn getDocumentSymbolsInternal(allocator: *std.mem.Allocator, tree: ast.Tree, nod .container_field_init, .tagged_union_enum_tag, .tagged_union_enum_tag_trailing, + .tagged_union, + .tagged_union_trailing, + .tagged_union_two, + .tagged_union_two_trailing, => .Field, else => .Variable, }, @@ -1647,14 +1692,16 @@ fn getDocumentSymbolsInternal(allocator: *std.mem.Allocator, tree: ast.Tree, nod .encoding = context.encoding, }; - var index: usize = 0; - if (true) @panic("FIX: addOutlineNodes"); - // try addOutlineNodes(allocator, tree, node, &child_context); - - // while (node.iterate(index)) |child| : (index += 1) { - // try addOutlineNodes(allocator, tree, child, &child_context); - // } + if (isContainer(tags[node])) { + var buf: [2]ast.Node.Index = undefined; + for (declMembers(tree, tags[node], node, &buf)) |child| + try addOutlineNodes(allocator, tree, child, &child_context); + } + if (varDecl(tree, node)) |var_decl| { + if (var_decl.ast.init_node != 0) + try addOutlineNodes(allocator, tree, var_decl.ast.init_node, &child_context); + } break :ch children.items; }, }; @@ -2056,7 +2103,7 @@ fn lookupSymbolGlobalInternal( source_index: usize, use_trail: *std.ArrayList(ast.Node.Index), ) error{OutOfMemory}!?DeclWithHandle { - for (handle.document_scope.scopes) |scope| { + for (handle.document_scope.scopes) |scope, i| { if (source_index >= scope.range.start and source_index < scope.range.end) { if (scope.decls.getEntry(symbol)) |candidate| { switch (candidate.value) { @@ -2266,10 +2313,10 @@ pub fn declMembers(tree: ast.Tree, tag: ast.Node.Tag, node_idx: ast.Node.Index, return switch (tag) { .container_decl, .container_decl_trailing => tree.containerDecl(node_idx).ast.members, .container_decl_arg, .container_decl_arg_trailing => tree.containerDeclArg(node_idx).ast.members, - .container_decl_two, .container_decl_two_trailing => tree.containerDeclTwo(&buffer, node_idx).ast.members, + .container_decl_two, .container_decl_two_trailing => tree.containerDeclTwo(buffer, node_idx).ast.members, .tagged_union, .tagged_union_trailing => tree.taggedUnion(node_idx).ast.members, .tagged_union_enum_tag, .tagged_union_enum_tag_trailing => tree.taggedUnionEnumTag(node_idx).ast.members, - .tagged_union_two, .tagged_union_two_trailing => tree.taggedUnionTwo(&buffer, node_idx).ast.members, + .tagged_union_two, .tagged_union_two_trailing => tree.taggedUnionTwo(buffer, node_idx).ast.members, .root => tree.rootDecls(), // @TODO: Fix error set declarations .error_set_decl => &[_]ast.Node.Index{}, @@ -2307,7 +2354,7 @@ fn makeScopeInternal( if (isContainer(node)) { var buf: [2]ast.Node.Index = undefined; - const ast_decls = declMembers(tree, node, node_idx); + const ast_decls = declMembers(tree, node, node_idx, &buf); (try scopes.addOne(allocator)).* = .{ .range = nodeSourceRange(tree, node_idx), @@ -2412,7 +2459,10 @@ fn makeScopeInternal( } switch (node) { - .fn_proto, .fn_proto_one, .fn_proto_simple, .fn_proto_multi, .fn_decl => { + .fn_decl => { + try makeScopeInternal(allocator, scopes, error_completions, enum_completions, tree, data[node_idx].rhs); + }, + .fn_proto, .fn_proto_one, .fn_proto_simple, .fn_proto_multi => { var buf: [1]ast.Node.Index = undefined; const func = fnProto(tree, node_idx, &buf).?; @@ -2435,10 +2485,6 @@ fn makeScopeInternal( } } - if (node == .fn_decl) { - try makeScopeInternal(allocator, scopes, error_completions, enum_completions, tree, data[node_idx].rhs); - } - return; }, .test_decl => { diff --git a/src/main.zig b/src/main.zig index 46c63d7..31cbc39 100644 --- a/src/main.zig +++ b/src/main.zig @@ -650,6 +650,7 @@ fn getLabelGlobal(pos_index: usize, handle: *DocumentStore.Handle) !?analysis.De fn getSymbolGlobal(arena: *std.heap.ArenaAllocator, pos_index: usize, handle: *DocumentStore.Handle) !?analysis.DeclWithHandle { const name = identifierFromPosition(pos_index, handle.*); + logger.debug("Name: {s}", .{name}); if (name.len == 0) return null; return try analysis.lookupSymbolGlobal(&document_store, arena, handle, name, pos_index); @@ -1314,7 +1315,6 @@ fn hoverHandler(arena: *std.heap.ArenaAllocator, id: types.RequestId, req: reque if (req.params.position.character >= 0) { const doc_position = try offsets.documentPosition(handle.document, req.params.position, offset_encoding); const pos_context = try analysis.documentPositionContext(arena, handle.document, doc_position); - switch (pos_context) { .builtin => try hoverDefinitionBuiltin(arena, id, doc_position.absolute_index, handle), .var_access => try hoverDefinitionGlobal(arena, id, doc_position.absolute_index, handle, config), diff --git a/src/offsets.zig b/src/offsets.zig index 8201924..40d40e0 100644 --- a/src/offsets.zig +++ b/src/offsets.zig @@ -71,14 +71,14 @@ pub const TokenLocation = struct { }; pub fn tokenRelativeLocation(tree: std.zig.ast.Tree, start_index: usize, token: std.zig.ast.TokenIndex, encoding: Encoding) !TokenLocation { - const token_loc = tree.tokenLocation(@truncate(u32, start_index), token); + const start = tree.tokens.items(.start)[token]; var loc = TokenLocation{ .line = 0, .column = 0, .offset = 0, }; - const token_start = token_loc.line_start; + const token_start = start; const source = tree.source[start_index..]; var i: usize = 0; while (i + start_index < token_start) { diff --git a/src/references.zig b/src/references.zig index 2361f7b..aba30c7 100644 --- a/src/references.zig +++ b/src/references.zig @@ -136,7 +136,7 @@ fn symbolReferencesInternal( // try symbolReferencesInternal(arena, store, .{ .node = use.expr, .handle = handle }, decl, encoding, context, handler); // }, .container_field, .container_field_align, .container_field_init => { - const field = analysis.containerField(node).?; + const field = analysis.containerField(tree, node).?; if (field.ast.type_expr != 0) { try symbolReferencesInternal(arena, store, .{ .node = field.ast.type_expr, .handle = handle }, decl, encoding, context, handler); } @@ -145,7 +145,7 @@ fn symbolReferencesInternal( } }, .identifier => { - if (try analysis.lookupSymbolGlobal(store, arena, handle, tree.getNodeSource(node), starts[main_tokens[nodes]])) |child| { + if (try analysis.lookupSymbolGlobal(store, arena, handle, tree.getNodeSource(node), starts[main_tokens[node]])) |child| { if (std.meta.eql(decl, child)) { try tokenReference(handle, main_tokens[node], encoding, context, handler); } @@ -204,14 +204,14 @@ fn symbolReferencesInternal( }, .switch_case => { const case = tree.switchCase(node); - for (case_one.ast.values) |val| + for (case.ast.values) |val| try symbolReferencesInternal(arena, store, .{ .node = val, .handle = handle }, decl, encoding, context, handler); }, - .@"while", .while_simple, .while_con, .for_simple, .@"for" => { + .@"while", .while_simple, .while_cont, .for_simple, .@"for" => { const loop: ast.full.While = switch (node_tags[node]) { .@"while" => tree.whileFull(node), .while_simple => tree.whileSimple(node), - .while_con => tree.whileCont(node), + .while_cont => tree.whileCont(node), .for_simple => tree.forSimple(node), .@"for" => tree.forFull(node), else => unreachable, @@ -276,7 +276,7 @@ fn symbolReferencesInternal( const array_init = switch (n) { .array_init, .array_init_comma => tree.arrayInit(node), .array_init_dot, .array_init_dot_comma => tree.arrayInitDot(node), - .array_init_one, .array_init_one_comma => tree.arrayInitOne(&buf[0..1], node), + .array_init_one, .array_init_one_comma => tree.arrayInitOne(buf[0..1], node), .array_init_dot_two, .array_init_dot_two_comma => tree.arrayInitDotTwo(&buf, node), else => unreachable, }; @@ -298,7 +298,7 @@ fn symbolReferencesInternal( const struct_init: ast.full.StructInit = switch (n) { .struct_init, .struct_init_comma => tree.structInit(node), .struct_init_dot, .struct_init_dot_comma => tree.structInitDot(node), - .struct_init_one, .struct_init_one_comma => tree.structInitOne(&buf[0..1], node), + .struct_init_one, .struct_init_one_comma => tree.structInitOne(buf[0..1], node), .struct_init_dot_two, .struct_init_dot_two_comma => tree.structInitDotTwo(&buf, node), else => unreachable, }; @@ -369,8 +369,7 @@ fn symbolReferencesInternal( .builtin_call_two, .builtin_call_two_comma, => { - const builtin_call = analysis.builtinCallParams(); - for (analysis.builtinCallParams()) |param| + for (analysis.builtinCallParams(tree, node)) |param| try symbolReferencesInternal(arena, store, .{ .node = param, .handle = handle }, decl, encoding, context, handler); }, .@"asm", .asm_simple => |a| { @@ -455,7 +454,7 @@ fn symbolReferencesInternal( .mod, .mul, .mul_wrap, - .range, + .switch_range, .sub, .sub_wrap, .@"orelse",