This commit is contained in:
agra
2026-02-14 22:26:58 +02:00
parent e7d2abdf0c
commit 3fd14bafac
4 changed files with 231 additions and 403 deletions

View File

@@ -455,10 +455,7 @@ pub const Analyzer = struct {
switch (node.data) {
.fn_decl => |fd| {
try self.pushScope();
for (fd.params) |param| {
const param_type = Type.fromTypeExpr(param.type_expr);
try self.addSymbol(param.name, .param, param_type, param.name_span);
}
try self.analyzeParams(fd.params);
try self.analyzeNode(fd.body);
self.popScope();
},
@@ -499,6 +496,13 @@ pub const Analyzer = struct {
}
}
fn analyzeParams(self: *Analyzer, params: []const ast.Param) !void {
for (params) |param| {
const param_type = Type.fromTypeExpr(param.type_expr);
try self.addSymbol(param.name, .param, param_type, param.name_span);
}
}
fn addSymbol(self: *Analyzer, name: []const u8, kind: SymbolKind, ty: ?Type, span: Span) !void {
// Check for duplicate only within the current scope window.
const scope_start: usize = if (self.scope_starts.items.len > 0)
@@ -563,11 +567,7 @@ pub const Analyzer = struct {
.fn_decl => |fd| {
try self.addSymbol(fd.name, .function, resolveReturnType(fd), node.span);
try self.pushScope();
// Add params as symbols
for (fd.params) |param| {
const param_type = Type.fromTypeExpr(param.type_expr);
try self.addSymbol(param.name, .param, param_type, param.name_span);
}
try self.analyzeParams(fd.params);
try self.analyzeNode(fd.body);
self.popScope();
},
@@ -675,10 +675,7 @@ pub const Analyzer = struct {
},
.lambda => |lam| {
try self.pushScope();
for (lam.params) |param| {
const param_type = Type.fromTypeExpr(param.type_expr);
try self.addSymbol(param.name, .param, param_type, param.name_span);
}
try self.analyzeParams(lam.params);
try self.analyzeNode(lam.body);
self.popScope();
},
@@ -824,24 +821,22 @@ pub fn analyzeSource(allocator: std.mem.Allocator, root: *Node) !SemaResult {
return analyzer.analyze(root);
}
/// Find the symbol whose definition span contains the given byte offset.
pub fn findSymbolAtOffset(symbols: []const Symbol, offset: u32) ?usize {
for (symbols, 0..) |sym, i| {
if (offset >= sym.def_span.start and offset < sym.def_span.end) {
return i;
}
fn findSpanAtOffset(comptime T: type, items: []const T, offset: u32, comptime span_field: []const u8) ?usize {
for (items, 0..) |item, i| {
const span = @field(item, span_field);
if (offset >= span.start and offset < span.end) return i;
}
return null;
}
/// Find the symbol whose definition span contains the given byte offset.
pub fn findSymbolAtOffset(symbols: []const Symbol, offset: u32) ?usize {
return findSpanAtOffset(Symbol, symbols, offset, "def_span");
}
/// Find the reference at the given byte offset.
pub fn findReferenceAtOffset(references: []const Reference, offset: u32) ?usize {
for (references, 0..) |ref_, i| {
if (offset >= ref_.span.start and offset < ref_.span.end) {
return i;
}
}
return null;
return findSpanAtOffset(Reference, references, offset, "span");
}
/// Walk the AST to find the innermost node whose span contains the offset.