From 14749ce02b96951a1c830810deb24148aa944852 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Sun, 17 May 2020 18:21:02 +0300 Subject: [PATCH 1/7] Added missing errdefer --- src/document_store.zig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/document_store.zig b/src/document_store.zig index 7d52f57..478fd08 100644 --- a/src/document_store.zig +++ b/src/document_store.zig @@ -316,7 +316,9 @@ pub const AnalysisContext = struct { // Swap handles and get new tree. // This takes ownership of the passed uri and text. - self.handle = try newDocument(self.store, try std.mem.dupe(allocator, u8, final_uri), file_contents); + const duped_final_uri = try std.mem.dupe(allocator, u8, final_uri); + errdefer allocator.free(duped_final_uri); + self.handle = try newDocument(self.store, duped_final_uri, file_contents); } // Free old tree, add new one if it exists. From 6a4dc3334a5fa8dbdddbb9c8e48bd67413dd93b3 Mon Sep 17 00:00:00 2001 From: Timon Kruiper Date: Sun, 17 May 2020 19:26:02 +0200 Subject: [PATCH 2/7] Wrap stdout in BufferedOutStream for more speed gotta go fast right :D Also remove some unused code --- src/main.zig | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/main.zig b/src/main.zig index a5d78fe..c8a3750 100644 --- a/src/main.zig +++ b/src/main.zig @@ -11,7 +11,7 @@ const analysis = @import("analysis.zig"); // Code is largely based off of https://github.com/andersfr/zig-lsp/blob/master/server.zig -var stdout: std.fs.File.OutStream = undefined; +var stdout: std.io.BufferedOutStream(4096, std.fs.File.OutStream) = undefined; var allocator: *std.mem.Allocator = undefined; var document_store: DocumentStore = undefined; @@ -46,8 +46,11 @@ fn send(reqOrRes: var) !void { var mem_buffer: [1024 * 128]u8 = undefined; var fbs = std.io.fixedBufferStream(&mem_buffer); try std.json.stringify(reqOrRes, std.json.StringifyOptions{}, fbs.outStream()); - try stdout.print("Content-Length: {}\r\n\r\n", .{fbs.pos}); - try stdout.writeAll(fbs.getWritten()); + + const stdout_stream = stdout.outStream(); + try stdout_stream.print("Content-Length: {}\r\n\r\n", .{fbs.pos}); + try stdout_stream.writeAll(fbs.getWritten()); + try stdout.flush(); } fn log(comptime fmt: []const u8, args: var) !void { @@ -82,8 +85,11 @@ fn respondGeneric(id: i64, response: []const u8) !void { // Numbers of character that will be printed from this string: len - 3 brackets // 1 from the beginning (escaped) and the 2 from the arg {} const json_fmt = "{{\"jsonrpc\":\"2.0\",\"id\":{}"; - try stdout.print("Content-Length: {}\r\n\r\n" ++ json_fmt, .{ response.len + id_digits + json_fmt.len - 3, id }); - try stdout.writeAll(response); + + const stdout_stream = stdout.outStream(); + try stdout_stream.print("Content-Length: {}\r\n\r\n" ++ json_fmt, .{ response.len + id_digits + json_fmt.len - 3, id }); + try stdout_stream.writeAll(response); + try stdout.flush(); } // TODO: Is this correct or can we get a better end? @@ -609,17 +615,9 @@ pub fn main() anyerror!void { allocator = &debug_alloc_state.allocator; } - // Init buffer for stdin read - - var buffer = std.ArrayList(u8).init(allocator); - defer buffer.deinit(); - - try buffer.resize(4096); - // Init global vars - const stdin = std.io.getStdIn().inStream(); - stdout = std.io.getStdOut().outStream(); + stdout = std.io.bufferedOutStream(std.io.getStdOut().outStream()); // Read the configuration, if any. const config_parse_options = std.json.ParseOptions{ .allocator = allocator }; From 4ad33c16f9b0236cc23461e67067e80e35d049d0 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Mon, 18 May 2020 14:26:52 +0300 Subject: [PATCH 3/7] Fixed crash when field access completing on a local variable from a type coming from an import --- src/analysis.zig | 66 +++++++++++++----------------------------- src/document_store.zig | 15 +++++++++- src/main.zig | 7 ++--- 3 files changed, 37 insertions(+), 51 deletions(-) diff --git a/src/analysis.zig b/src/analysis.zig index 91a2f00..25be7b5 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -234,7 +234,6 @@ pub fn getChildOfSlice(tree: *ast.Tree, nodes: []*ast.Node, name: []const u8) ?* /// Resolves the type of a node pub fn resolveTypeOfNode(analysis_ctx: *AnalysisContext, node: *ast.Node) ?*ast.Node { - std.debug.warn("NODE {}\n", .{node}); switch (node.id) { .VarDecl => { const vari = node.cast(ast.Node.VarDecl).?; @@ -257,9 +256,9 @@ pub fn resolveTypeOfNode(analysis_ctx: *AnalysisContext, node: *ast.Node) ?*ast. } }, .Identifier => { - // std.debug.warn("IDENTIFIER {}\n", .{analysis_ctx.tree.getNodeSource(node)}); - if (getChildOfSlice(analysis_ctx.tree, analysis_ctx.scope_nodes, analysis_ctx.tree.getNodeSource(node))) |child| { - // std.debug.warn("CHILD {}\n", .{child}); + const identifier = std.mem.dupe(&analysis_ctx.arena.allocator, u8, analysis_ctx.tree.getNodeSource(node)) catch return null; + + if (getChildOfSlice(analysis_ctx.tree, analysis_ctx.scope_nodes, identifier)) |child| { return resolveTypeOfNode(analysis_ctx, child); } else return null; }, @@ -391,9 +390,8 @@ pub fn getFieldAccessTypeNode(analysis_ctx: *AnalysisContext, tokenizer: *std.zi return current_node; }, .Identifier => { - // var root = current_node.cast(ast.Node.Root).?; - // current_node. - if (getChildOfSlice(analysis_ctx.tree, analysis_ctx.scope_nodes, tokenizer.buffer[next.start..next.end])) |child| { + const identifier = std.mem.dupe(&analysis_ctx.arena.allocator, u8, tokenizer.buffer[next.start..next.end]) catch return null; + if (getChildOfSlice(analysis_ctx.tree, analysis_ctx.scope_nodes, identifier)) |child| { if (resolveTypeOfNode(analysis_ctx, child)) |node_type| { current_node = node_type; } else return null; @@ -462,70 +460,46 @@ pub fn nodeToString(tree: *ast.Tree, node: *ast.Node) ?[]const u8 { return null; } -pub fn declsFromIndexInternal(allocator: *std.mem.Allocator, tree: *ast.Tree, node: *ast.Node, nodes: *std.ArrayList(*ast.Node)) anyerror!void { +pub fn declsFromIndexInternal(decls: *std.ArrayList(*ast.Node), tree: *ast.Tree, node: *ast.Node) anyerror!void { switch (node.id) { .FnProto => { const func = node.cast(ast.Node.FnProto).?; var param_index: usize = 0; while (param_index < func.params.len) : (param_index += 1) - try declsFromIndexInternal(allocator, tree, func.params.at(param_index).*, nodes); + try declsFromIndexInternal(decls, tree, func.params.at(param_index).*); if (func.body_node) |body_node| - try declsFromIndexInternal(allocator, tree, body_node, nodes); + try declsFromIndexInternal(decls, tree, body_node); }, .Block => { var index: usize = 0; while (node.iterate(index)) |inode| { - try declsFromIndexInternal(allocator, tree, inode, nodes); + try declsFromIndexInternal(decls, tree, inode); index += 1; } }, - .VarDecl => { - try nodes.append(node); - }, - .ParamDecl => { - try nodes.append(node); - }, - else => { - try nodes.appendSlice(try getCompletionsFromNode(allocator, tree, node)); - }, + .VarDecl, .ParamDecl => try decls.append(node), + else => try getCompletionsFromNode(decls, tree, node), } } -pub fn getCompletionsFromNode(allocator: *std.mem.Allocator, tree: *ast.Tree, node: *ast.Node) ![]*ast.Node { - var nodes = std.ArrayList(*ast.Node).init(allocator); - +pub fn getCompletionsFromNode(decls: *std.ArrayList(*ast.Node), tree: *ast.Tree, node: *ast.Node) !void { var index: usize = 0; - while (node.iterate(index)) |child_node| { - try nodes.append(child_node); - - index += 1; + while (node.iterate(index)) |child_node| : (index += 1) { + try decls.append(child_node); } - - return nodes.items; } -pub fn declsFromIndex(allocator: *std.mem.Allocator, tree: *ast.Tree, index: usize) ![]*ast.Node { - var iindex: usize = 0; - +pub fn declsFromIndex(decls: *std.ArrayList(*ast.Node), tree: *ast.Tree, index: usize) !void { var node = &tree.root_node.base; - var nodes = std.ArrayList(*ast.Node).init(allocator); - try nodes.appendSlice(try getCompletionsFromNode(allocator, tree, node)); - - while (node.iterate(iindex)) |inode| { - if (tree.tokens.at(inode.firstToken()).start < index and index < tree.tokens.at(inode.lastToken()).start) { - try declsFromIndexInternal(allocator, tree, inode, &nodes); + try getCompletionsFromNode(decls, tree, node); + var node_index: usize = 0; + while (node.iterate(node_index)) |inode| : (node_index += 1) { + if (tree.tokens.at(inode.firstToken()).start < index and index < tree.tokens.at(inode.lastToken()).end) { + try declsFromIndexInternal(decls, tree, inode); } - - iindex += 1; } - - if (tree.tokens.at(node.firstToken()).start < index and index < tree.tokens.at(node.lastToken()).start) { - return nodes.items; - } - - return nodes.items; } diff --git a/src/document_store.zig b/src/document_store.zig index 478fd08..d8e0cad 100644 --- a/src/document_store.zig +++ b/src/document_store.zig @@ -257,6 +257,12 @@ pub const AnalysisContext = struct { tree: *std.zig.ast.Tree, scope_nodes: []*std.zig.ast.Node, + fn refreshScopeNodes(self: *AnalysisContext) !void { + var scope_nodes = std.ArrayList(*std.zig.ast.Node).init(&self.arena.allocator); + try analysis.getCompletionsFromNode(&scope_nodes, self.tree, &self.tree.root_node.base); + self.scope_nodes = scope_nodes.items; + } + pub fn onImport(self: *AnalysisContext, import_str: []const u8) !?*std.zig.ast.Node { const allocator = self.store.allocator; const final_uri = (try uriFromImportStr(self.store, self.handle.*, import_str)) orelse return null; @@ -273,6 +279,7 @@ pub const AnalysisContext = struct { self.tree.deinit(); self.tree = try self.handle.tree(allocator); + try self.refreshScopeNodes(); return &self.tree.root_node.base; } } @@ -286,6 +293,7 @@ pub const AnalysisContext = struct { self.tree.deinit(); self.tree = try self.handle.tree(allocator); + try self.refreshScopeNodes(); return &self.tree.root_node.base; } @@ -325,6 +333,7 @@ pub const AnalysisContext = struct { // If we return null, no one should access the tree. self.tree.deinit(); self.tree = try self.handle.tree(allocator); + try self.refreshScopeNodes(); return &self.tree.root_node.base; } @@ -335,12 +344,16 @@ pub const AnalysisContext = struct { pub fn analysisContext(self: *DocumentStore, handle: *Handle, arena: *std.heap.ArenaAllocator, position: types.Position) !AnalysisContext { const tree = try handle.tree(self.allocator); + + var scope_nodes = std.ArrayList(*std.zig.ast.Node).init(&arena.allocator); + try analysis.declsFromIndex(&scope_nodes, tree, try handle.document.positionToIndex(position)); + return AnalysisContext{ .store = self, .handle = handle, .arena = arena, .tree = tree, - .scope_nodes = try analysis.declsFromIndex(&arena.allocator, tree, try handle.document.positionToIndex(position)) + .scope_nodes = scope_nodes.items, }; } diff --git a/src/main.zig b/src/main.zig index a5d78fe..450a430 100644 --- a/src/main.zig +++ b/src/main.zig @@ -280,9 +280,9 @@ fn completeGlobal(id: i64, pos_index: usize, handle: DocumentStore.Handle, confi // Deallocate all temporary data. defer arena.deinit(); - // var decls = tree.root_node.decls.iterator(0); - var decls = try analysis.declsFromIndex(&arena.allocator, tree, pos_index); - for (decls) |decl_ptr| { + var decl_nodes = std.ArrayList(*std.zig.ast.Node).init(&arena.allocator); + try analysis.declsFromIndex(&decl_nodes, tree, pos_index); + for (decl_nodes.items) |decl_ptr| { var decl = decl_ptr.*; try nodeToCompletion(&completions, tree, decl_ptr, config); } @@ -310,7 +310,6 @@ fn completeFieldAccess(id: i64, handle: *DocumentStore.Handle, position: types.P const line = try handle.document.getLine(@intCast(usize, position.line)); var tokenizer = std.zig.Tokenizer.init(line[line_start_idx..]); - // var decls = try analysis.declsFromIndex(&arena.allocator, analysis_ctx.tree, try handle.document.positionToIndex(position)); if (analysis.getFieldAccessTypeNode(&analysis_ctx, &tokenizer)) |node| { try nodeToCompletion(&completions, analysis_ctx.tree, node, config); } From e65d3388e45c9df06294c576512387b6a4d570d9 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Mon, 18 May 2020 14:53:40 +0300 Subject: [PATCH 4/7] A couple of more changes --- src/analysis.zig | 16 +++++----------- src/document_store.zig | 2 +- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/analysis.zig b/src/analysis.zig index 25be7b5..33322b3 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -206,7 +206,6 @@ pub fn getChild(tree: *ast.Tree, node: *ast.Node, name: []const u8) ?*ast.Node { /// Gets the child of slice pub fn getChildOfSlice(tree: *ast.Tree, nodes: []*ast.Node, name: []const u8) ?*ast.Node { - // var index: usize = 0; for (nodes) |child| { switch (child.id) { .VarDecl => { @@ -227,7 +226,6 @@ pub fn getChildOfSlice(tree: *ast.Tree, nodes: []*ast.Node, name: []const u8) ?* }, else => {}, } - // index += 1; } return null; } @@ -386,9 +384,7 @@ pub fn getFieldAccessTypeNode(analysis_ctx: *AnalysisContext, tokenizer: *std.zi while (true) { var next = tokenizer.next(); switch (next.id) { - .Eof => { - return current_node; - }, + .Eof => return current_node, .Identifier => { const identifier = std.mem.dupe(&analysis_ctx.arena.allocator, u8, tokenizer.buffer[next.start..next.end]) catch return null; if (getChildOfSlice(analysis_ctx.tree, analysis_ctx.scope_nodes, identifier)) |child| { @@ -409,9 +405,7 @@ pub fn getFieldAccessTypeNode(analysis_ctx: *AnalysisContext, tokenizer: *std.zi } else return null; } }, - else => { - std.debug.warn("Not implemented; {}\n", .{next.id}); - }, + else => std.debug.warn("Not implemented; {}\n", .{next.id}), } } @@ -481,11 +475,11 @@ pub fn declsFromIndexInternal(decls: *std.ArrayList(*ast.Node), tree: *ast.Tree, } }, .VarDecl, .ParamDecl => try decls.append(node), - else => try getCompletionsFromNode(decls, tree, node), + else => try addChildrenNodes(decls, tree, node), } } -pub fn getCompletionsFromNode(decls: *std.ArrayList(*ast.Node), tree: *ast.Tree, node: *ast.Node) !void { +pub fn addChildrenNodes(decls: *std.ArrayList(*ast.Node), tree: *ast.Tree, node: *ast.Node) !void { var index: usize = 0; while (node.iterate(index)) |child_node| : (index += 1) { try decls.append(child_node); @@ -495,7 +489,7 @@ pub fn getCompletionsFromNode(decls: *std.ArrayList(*ast.Node), tree: *ast.Tree, pub fn declsFromIndex(decls: *std.ArrayList(*ast.Node), tree: *ast.Tree, index: usize) !void { var node = &tree.root_node.base; - try getCompletionsFromNode(decls, tree, node); + try addChildrenNodes(decls, tree, node); var node_index: usize = 0; while (node.iterate(node_index)) |inode| : (node_index += 1) { if (tree.tokens.at(inode.firstToken()).start < index and index < tree.tokens.at(inode.lastToken()).end) { diff --git a/src/document_store.zig b/src/document_store.zig index d8e0cad..c745e82 100644 --- a/src/document_store.zig +++ b/src/document_store.zig @@ -259,7 +259,7 @@ pub const AnalysisContext = struct { fn refreshScopeNodes(self: *AnalysisContext) !void { var scope_nodes = std.ArrayList(*std.zig.ast.Node).init(&self.arena.allocator); - try analysis.getCompletionsFromNode(&scope_nodes, self.tree, &self.tree.root_node.base); + try analysis.addChildrenNodes(&scope_nodes, self.tree, &self.tree.root_node.base); self.scope_nodes = scope_nodes.items; } From 96672435a798a223739266ac0b71b06a1034fb49 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Mon, 18 May 2020 14:55:39 +0300 Subject: [PATCH 5/7] Removed unnecessary copies --- src/analysis.zig | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/analysis.zig b/src/analysis.zig index 33322b3..b3dcb8f 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -254,9 +254,7 @@ pub fn resolveTypeOfNode(analysis_ctx: *AnalysisContext, node: *ast.Node) ?*ast. } }, .Identifier => { - const identifier = std.mem.dupe(&analysis_ctx.arena.allocator, u8, analysis_ctx.tree.getNodeSource(node)) catch return null; - - if (getChildOfSlice(analysis_ctx.tree, analysis_ctx.scope_nodes, identifier)) |child| { + if (getChildOfSlice(analysis_ctx.tree, analysis_ctx.scope_nodes, analysis_ctx.tree.getNodeSource(node))) |child| { return resolveTypeOfNode(analysis_ctx, child); } else return null; }, @@ -386,8 +384,7 @@ pub fn getFieldAccessTypeNode(analysis_ctx: *AnalysisContext, tokenizer: *std.zi switch (next.id) { .Eof => return current_node, .Identifier => { - const identifier = std.mem.dupe(&analysis_ctx.arena.allocator, u8, tokenizer.buffer[next.start..next.end]) catch return null; - if (getChildOfSlice(analysis_ctx.tree, analysis_ctx.scope_nodes, identifier)) |child| { + if (getChildOfSlice(analysis_ctx.tree, analysis_ctx.scope_nodes, tokenizer.buffer[next.start..next.end])) |child| { if (resolveTypeOfNode(analysis_ctx, child)) |node_type| { current_node = node_type; } else return null; From 749a4fcbe44cc80c37342af117f3f699550edaa5 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Mon, 18 May 2020 15:14:16 +0300 Subject: [PATCH 6/7] Renamed checkSanity to removeOldImports, use an arena for temporary data. --- src/analysis.zig | 10 +++------- src/document_store.zig | 41 ++++++++++++++++++++--------------------- 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/src/analysis.zig b/src/analysis.zig index b3dcb8f..a9db2e0 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -344,10 +344,8 @@ fn maybeCollectImport(tree: *ast.Tree, builtin_call: *ast.Node.BuiltinCall, arr: /// Collects all imports we can find into a slice of import paths (without quotes). /// The import paths are valid as long as the tree is. -pub fn collectImports(allocator: *std.mem.Allocator, tree: *ast.Tree) ![][]const u8 { +pub fn collectImports(import_arr: *std.ArrayList([]const u8), tree: *ast.Tree) !void { // TODO: Currently only detects `const smth = @import("string literal")<.SometThing>;` - var arr = std.ArrayList([]const u8).init(allocator); - var idx: usize = 0; while (tree.root_node.iterate(idx)) |decl| : (idx += 1) { if (decl.id != .VarDecl) continue; @@ -357,7 +355,7 @@ pub fn collectImports(allocator: *std.mem.Allocator, tree: *ast.Tree) ![][]const switch (var_decl.init_node.?.id) { .BuiltinCall => { const builtin_call = var_decl.init_node.?.cast(ast.Node.BuiltinCall).?; - try maybeCollectImport(tree, builtin_call, &arr); + try maybeCollectImport(tree, builtin_call, import_arr); }, .InfixOp => { const infix_op = var_decl.init_node.?.cast(ast.Node.InfixOp).?; @@ -367,13 +365,11 @@ pub fn collectImports(allocator: *std.mem.Allocator, tree: *ast.Tree) ![][]const else => continue, } if (infix_op.lhs.id != .BuiltinCall) continue; - try maybeCollectImport(tree, infix_op.lhs.cast(ast.Node.BuiltinCall).?, &arr); + try maybeCollectImport(tree, infix_op.lhs.cast(ast.Node.BuiltinCall).?, import_arr); }, else => {}, } } - - return arr.toOwnedSlice(); } pub fn getFieldAccessTypeNode(analysis_ctx: *AnalysisContext, tokenizer: *std.zig.Tokenizer) ?*ast.Node { diff --git a/src/document_store.zig b/src/document_store.zig index c745e82..02dd85f 100644 --- a/src/document_store.zig +++ b/src/document_store.zig @@ -61,7 +61,6 @@ fn newDocument(self: *DocumentStore, uri: []const u8, text: []u8) !*Handle { .mem = text, }, }; - try self.checkSanity(&handle); const kv = try self.handles.getOrPutValue(uri, handle); return &kv.value; } @@ -117,10 +116,7 @@ pub fn getHandle(self: *DocumentStore, uri: []const u8) ?*Handle { } // Check if the document text is now sane, move it to sane_text if so. -fn checkSanity(self: *DocumentStore, handle: *Handle) !void { - const tree = try handle.tree(self.allocator); - defer tree.deinit(); - +fn removeOldImports(self: *DocumentStore, handle: *Handle) !void { std.debug.warn("New text for document {}\n", .{handle.uri()}); // TODO: Better algorithm or data structure? // Removing the imports is costly since they live in an array list @@ -129,19 +125,22 @@ fn checkSanity(self: *DocumentStore, handle: *Handle) !void { // Try to detect removed imports and decrement their counts. if (handle.import_uris.items.len == 0) return; - const import_strs = try analysis.collectImports(self.allocator, tree); - defer self.allocator.free(import_strs); + const tree = try handle.tree(self.allocator); + defer tree.deinit(); - const still_exist = try self.allocator.alloc(bool, handle.import_uris.items.len); - defer self.allocator.free(still_exist); + var arena = std.heap.ArenaAllocator.init(self.allocator); + defer arena.deinit(); + var import_strs = std.ArrayList([]const u8).init(&arena.allocator); + try analysis.collectImports(&import_strs, tree); + + const still_exist = try arena.allocator.alloc(bool, handle.import_uris.items.len); for (still_exist) |*ex| { ex.* = false; } - for (import_strs) |str| { - const uri = (try uriFromImportStr(self, handle.*, str)) orelse continue; - defer self.allocator.free(uri); + for (import_strs.items) |str| { + const uri = (try uriFromImportStr(self, &arena.allocator, handle.*, str)) orelse continue; var idx: usize = 0; exists_loop: while (idx < still_exist.len) : (idx += 1) { @@ -222,29 +221,29 @@ pub fn applyChanges(self: *DocumentStore, handle: *Handle, content_changes: std. } } - try self.checkSanity(handle); + try self.removeOldImports(handle); } -fn uriFromImportStr(store: *DocumentStore, handle: Handle, import_str: []const u8) !?[]const u8 { +fn uriFromImportStr(store: *DocumentStore, allocator: *std.mem.Allocator, handle: Handle, import_str: []const u8) !?[]const u8 { return if (std.mem.eql(u8, import_str, "std")) - if (store.std_uri) |std_root_uri| try std.mem.dupe(store.allocator, u8, std_root_uri) + if (store.std_uri) |std_root_uri| try std.mem.dupe(allocator, u8, std_root_uri) else { std.debug.warn("Cannot resolve std library import, path is null.\n", .{}); return null; } else b: { // Find relative uri - const path = try URI.parse(store.allocator, handle.uri()); - defer store.allocator.free(path); + const path = try URI.parse(allocator, handle.uri()); + defer allocator.free(path); const dir_path = std.fs.path.dirname(path) orelse ""; - const import_path = try std.fs.path.resolve(store.allocator, &[_][]const u8 { + const import_path = try std.fs.path.resolve(allocator, &[_][]const u8 { dir_path, import_str }); - defer store.allocator.free(import_path); + defer allocator.free(import_path); - break :b (try URI.fromPath(store.allocator, import_path)); + break :b (try URI.fromPath(allocator, import_path)); }; } @@ -265,7 +264,7 @@ pub const AnalysisContext = struct { pub fn onImport(self: *AnalysisContext, import_str: []const u8) !?*std.zig.ast.Node { const allocator = self.store.allocator; - const final_uri = (try uriFromImportStr(self.store, self.handle.*, import_str)) orelse return null; + const final_uri = (try uriFromImportStr(self.store, self.store.allocator, self.handle.*, import_str)) orelse return null; std.debug.warn("Import final URI: {}\n", .{final_uri}); var consumed_final_uri = false; From a6a4afd4fdb7f8af7dfb8861f2f19a4801a306e5 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Mon, 18 May 2020 15:46:17 +0300 Subject: [PATCH 7/7] More cleanup: --- src/analysis.zig | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/analysis.zig b/src/analysis.zig index a9db2e0..04dbcd9 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -258,16 +258,10 @@ pub fn resolveTypeOfNode(analysis_ctx: *AnalysisContext, node: *ast.Node) ?*ast. return resolveTypeOfNode(analysis_ctx, child); } else return null; }, - .ContainerDecl => { - return node; - }, .ContainerField => { const field = node.cast(ast.Node.ContainerField).?; return resolveTypeOfNode(analysis_ctx, field.type_expr orelse return null); }, - .ErrorSetDecl => { - return node; - }, .SuffixOp => { const suffix_op = node.cast(ast.Node.SuffixOp).?; switch (suffix_op.op) { @@ -321,12 +315,8 @@ pub fn resolveTypeOfNode(analysis_ctx: *AnalysisContext, node: *ast.Node) ?*ast. break :block null; }; }, - .MultilineStringLiteral, .StringLiteral => { - return node; - }, - else => { - std.debug.warn("Type resolution case not implemented; {}\n", .{node.id}); - }, + .MultilineStringLiteral, .StringLiteral, .ContainerDecl, .ErrorSetDecl => return node, + else => std.debug.warn("Type resolution case not implemented; {}\n", .{node.id}), } return null; } @@ -345,7 +335,7 @@ fn maybeCollectImport(tree: *ast.Tree, builtin_call: *ast.Node.BuiltinCall, arr: /// Collects all imports we can find into a slice of import paths (without quotes). /// The import paths are valid as long as the tree is. pub fn collectImports(import_arr: *std.ArrayList([]const u8), tree: *ast.Tree) !void { - // TODO: Currently only detects `const smth = @import("string literal")<.SometThing>;` + // TODO: Currently only detects `const smth = @import("string literal")<.SomeThing>;` var idx: usize = 0; while (tree.root_node.iterate(idx)) |decl| : (idx += 1) { if (decl.id != .VarDecl) continue; @@ -461,10 +451,8 @@ pub fn declsFromIndexInternal(decls: *std.ArrayList(*ast.Node), tree: *ast.Tree, }, .Block => { var index: usize = 0; - - while (node.iterate(index)) |inode| { + while (node.iterate(index)) |inode| : (index += 1) { try declsFromIndexInternal(decls, tree, inode); - index += 1; } }, .VarDecl, .ParamDecl => try decls.append(node),