fix: "f..o.o;" crashes the server (#629)
this is a fix for #381 and a hack for #409 (related, get triggered by "f..o.o;")
This commit is contained in:
parent
aa81d83136
commit
6269eef776
@ -808,8 +808,8 @@ pub fn resolveTypeOfNodeInternal(store: *DocumentStore, arena: *std.heap.ArenaAl
|
|||||||
},
|
},
|
||||||
.field_access => {
|
.field_access => {
|
||||||
if (datas[node].rhs == 0) return null;
|
if (datas[node].rhs == 0) return null;
|
||||||
if (node >= tree.nodes.len - 1) return null; // #boundsCheck
|
const rhs_str = ast.tokenSlice(tree, datas[node].rhs) catch return null;
|
||||||
const rhs_str = tree.tokenSlice(datas[node].rhs);
|
|
||||||
// If we are accessing a pointer type, remove one pointerness level :)
|
// If we are accessing a pointer type, remove one pointerness level :)
|
||||||
const left_type = try resolveFieldAccessLhsType(
|
const left_type = try resolveFieldAccessLhsType(
|
||||||
store,
|
store,
|
||||||
@ -1342,7 +1342,7 @@ pub fn nodeToString(tree: Ast, node: Ast.Node.Index) ?[]const u8 {
|
|||||||
.fn_decl,
|
.fn_decl,
|
||||||
=> if (ast.fnProto(tree, node, &buf).?.name_token) |name|
|
=> if (ast.fnProto(tree, node, &buf).?.name_token) |name|
|
||||||
return tree.tokenSlice(name),
|
return tree.tokenSlice(name),
|
||||||
.field_access => return tree.tokenSlice(data[node].rhs),
|
.field_access => return ast.tokenSlice(tree, data[node].rhs) catch return null,
|
||||||
.call,
|
.call,
|
||||||
.call_comma,
|
.call_comma,
|
||||||
.async_call,
|
.async_call,
|
||||||
|
23
src/ast.zig
23
src/ast.zig
@ -1215,3 +1215,26 @@ pub fn nextFnParam(it: *Ast.full.FnProto.Iterator) ?Ast.full.FnProto.Param {
|
|||||||
it.tok_flag = false;
|
it.tok_flag = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A modified version of tree.tokenSlice that returns an error.UnexpectedToken if the tokenizer encounters an unexpected token
|
||||||
|
// https://github.com/zigtools/zls/issues/381
|
||||||
|
pub fn tokenSlice(tree: Ast, token_index: Ast.TokenIndex) ![]const u8 {
|
||||||
|
const token_starts = tree.tokens.items(.start);
|
||||||
|
const token_tags = tree.tokens.items(.tag);
|
||||||
|
const token_tag = token_tags[token_index];
|
||||||
|
|
||||||
|
// Many tokens can be determined entirely by their tag.
|
||||||
|
if (token_tag.lexeme()) |lexeme| {
|
||||||
|
return lexeme;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For some tokens, re-tokenization is needed to find the end.
|
||||||
|
var tokenizer: std.zig.Tokenizer = .{
|
||||||
|
.buffer = tree.source,
|
||||||
|
.index = token_starts[token_index],
|
||||||
|
.pending_invalid_token = null,
|
||||||
|
};
|
||||||
|
const token = tokenizer.next();
|
||||||
|
if (token.tag != token_tag) return error.UnexpectedToken; // assert(token.tag == token_tag);
|
||||||
|
return tree.source[token.loc.start..token.loc.end];
|
||||||
|
}
|
||||||
|
@ -182,7 +182,8 @@ pub fn tokenLocation(tree: Ast, token_index: Ast.TokenIndex) Loc {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const token = tokenizer.next();
|
const token = tokenizer.next();
|
||||||
std.debug.assert(token.tag == tag);
|
// HACK, should return error.UnextectedToken
|
||||||
|
if (token.tag != tag) return .{ .start = 0, .end = 0 }; //std.debug.assert(token.tag == tag);
|
||||||
return .{ .start = token.loc.start, .end = token.loc.end };
|
return .{ .start = token.loc.start, .end = token.loc.end };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +382,7 @@ fn symbolReferencesInternal(arena: *std.heap.ArenaAllocator, store: *DocumentSto
|
|||||||
.field_access => {
|
.field_access => {
|
||||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].lhs, .handle = handle }, decl, encoding, context, handler);
|
try symbolReferencesInternal(arena, store, .{ .node = datas[node].lhs, .handle = handle }, decl, encoding, context, handler);
|
||||||
|
|
||||||
const rhs_str = tree.tokenSlice(datas[node].rhs);
|
const rhs_str = ast.tokenSlice(tree, datas[node].rhs) catch return;
|
||||||
var bound_type_params = analysis.BoundTypeParams{};
|
var bound_type_params = analysis.BoundTypeParams{};
|
||||||
const left_type = try analysis.resolveFieldAccessLhsType(
|
const left_type = try analysis.resolveFieldAccessLhsType(
|
||||||
store,
|
store,
|
||||||
|
@ -854,7 +854,7 @@ fn writeNodeTokens(builder: *Builder, arena: *std.heap.ArenaAllocator, store: *D
|
|||||||
.field_access => {
|
.field_access => {
|
||||||
const data = node_data[node];
|
const data = node_data[node];
|
||||||
if (data.rhs == 0) return;
|
if (data.rhs == 0) return;
|
||||||
const rhs_str = tree.tokenSlice(data.rhs);
|
const rhs_str = ast.tokenSlice(tree, data.rhs) catch return;
|
||||||
|
|
||||||
try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, data.lhs });
|
try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, data.lhs });
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user