...
This commit is contained in:
65
src/sema.zig
65
src/sema.zig
@@ -539,7 +539,19 @@ pub const Analyzer = struct {
|
||||
|
||||
fn analyzeParams(self: *Analyzer, params: []const ast.Param) !void {
|
||||
for (params) |param| {
|
||||
const param_type = Type.fromTypeExpr(param.type_expr);
|
||||
self.resolveTypeRef(param.type_expr);
|
||||
const param_type = Type.fromTypeExpr(param.type_expr) orelse blk: {
|
||||
if (param.type_expr.data == .type_expr) {
|
||||
const name = param.type_expr.data.type_expr.name;
|
||||
const resolved = self.type_aliases.get(name) orelse name;
|
||||
if (self.symbol_index.get(resolved)) |indices| {
|
||||
for (indices.items) |idx| {
|
||||
if (self.symbols.items[idx].ty) |ty| break :blk ty;
|
||||
}
|
||||
}
|
||||
}
|
||||
break :blk null;
|
||||
};
|
||||
try self.addSymbol(param.name, .param, param_type, param.name_span);
|
||||
}
|
||||
}
|
||||
@@ -884,14 +896,63 @@ pub const Analyzer = struct {
|
||||
const resolved = self.type_aliases.get(name) orelse name;
|
||||
if (self.symbol_index.get(resolved)) |indices| {
|
||||
for (indices.items) |idx| {
|
||||
if (self.symbols.items[idx].ty) |ty| return ty;
|
||||
if (self.symbols.items[idx].ty) |ty| {
|
||||
// Register a reference so go-to-definition works on type names
|
||||
self.tryAddReference(resolved, tn.span);
|
||||
return ty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// For compound types (pointers, slices, arrays), resolve inner type refs
|
||||
self.resolveTypeRef(tn);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Try to create a reference for a name without emitting diagnostics.
|
||||
/// Used for type names where missing symbols are expected (primitives, builtins).
|
||||
fn tryAddReference(self: *Analyzer, name: []const u8, span: Span) void {
|
||||
if (self.symbol_index.get(name)) |indices| {
|
||||
var j = indices.items.len;
|
||||
while (j > 0) {
|
||||
j -= 1;
|
||||
const idx = indices.items[j];
|
||||
const sym = self.symbols.items[idx];
|
||||
if (sym.scope_depth <= self.scope_depth) {
|
||||
self.references.append(self.allocator, .{
|
||||
.span = span,
|
||||
.symbol_index = idx,
|
||||
}) catch {};
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Create references for type expression nodes so go-to-definition works on type names.
|
||||
/// Only resolves compound types (pointer/slice/array element types).
|
||||
fn resolveTypeRef(self: *Analyzer, node: *Node) void {
|
||||
switch (node.data) {
|
||||
.type_expr => |te| {
|
||||
self.tryAddReference(te.name, node.span);
|
||||
},
|
||||
.pointer_type_expr => |pte| {
|
||||
self.resolveTypeRef(pte.pointee_type);
|
||||
},
|
||||
.many_pointer_type_expr => |mpte| {
|
||||
self.resolveTypeRef(mpte.element_type);
|
||||
},
|
||||
.slice_type_expr => |ste| {
|
||||
self.resolveTypeRef(ste.element_type);
|
||||
},
|
||||
.array_type_expr => |ate| {
|
||||
self.resolveTypeRef(ate.element_type);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn inferValueType(value: *Node) ?Type {
|
||||
return switch (value.data) {
|
||||
.int_literal => Type.s(64),
|
||||
|
||||
Reference in New Issue
Block a user