...
This commit is contained in:
@@ -28,6 +28,8 @@ pub const Document = struct {
|
||||
last_good_sema: ?sx.sema.SemaResult = null,
|
||||
/// Import declarations parsed from this file.
|
||||
imports: []const Import,
|
||||
/// True while this document is being analyzed (circular import guard).
|
||||
is_analyzing: bool = false,
|
||||
|
||||
pub fn topLevelSymbols(self: *const Document) []const sx.sema.Symbol {
|
||||
const sr = self.sema orelse return &.{};
|
||||
@@ -115,6 +117,10 @@ pub const DocumentStore = struct {
|
||||
|
||||
/// Analyze a document: parse, resolve imports, run sema with imported symbols pre-registered.
|
||||
pub fn analyzeDocument(self: *DocumentStore, doc: *Document) !void {
|
||||
if (doc.is_analyzing) return; // circular import guard
|
||||
doc.is_analyzing = true;
|
||||
defer doc.is_analyzing = false;
|
||||
|
||||
// Parse if needed
|
||||
if (doc.root == null) {
|
||||
var p = sx.parser.Parser.init(self.allocator, doc.source);
|
||||
@@ -144,10 +150,6 @@ pub const DocumentStore = struct {
|
||||
// Recursively analyze imported documents and pre-register their symbols
|
||||
var analyzer = sx.sema.Analyzer.init(self.allocator);
|
||||
|
||||
// Track in-progress documents to detect cycles
|
||||
var cycle_guard = std.StringHashMap(void).init(self.allocator);
|
||||
try cycle_guard.put(doc.path, {});
|
||||
|
||||
for (doc.imports) |imp| {
|
||||
// Try as file first; if that fails, try as directory import
|
||||
const imp_doc = self.getOrLoad(imp.path) catch {
|
||||
@@ -155,11 +157,8 @@ pub const DocumentStore = struct {
|
||||
const dir_files = self.listDirectoryFiles(imp.path) orelse continue;
|
||||
for (dir_files) |file_path| {
|
||||
const file_doc = self.getOrLoad(file_path) catch continue;
|
||||
if (cycle_guard.contains(file_path)) continue;
|
||||
if (file_doc.sema == null) {
|
||||
try cycle_guard.put(file_path, {});
|
||||
self.analyzeDocument(file_doc) catch {};
|
||||
_ = cycle_guard.remove(file_path);
|
||||
}
|
||||
const file_sema = file_doc.sema orelse continue;
|
||||
if (imp.ns) |ns_name| {
|
||||
@@ -219,14 +218,9 @@ pub const DocumentStore = struct {
|
||||
continue;
|
||||
};
|
||||
|
||||
// Cycle detection
|
||||
if (cycle_guard.contains(imp.path)) continue;
|
||||
|
||||
// Ensure imported doc is analyzed
|
||||
if (imp_doc.sema == null) {
|
||||
try cycle_guard.put(imp.path, {});
|
||||
self.analyzeDocument(imp_doc) catch {};
|
||||
_ = cycle_guard.remove(imp.path);
|
||||
}
|
||||
|
||||
const imp_sema = imp_doc.sema orelse continue;
|
||||
|
||||
Reference in New Issue
Block a user