From 5b2f389f6bf48648ae7e8cbbf6835133075de18f Mon Sep 17 00:00:00 2001 From: dalance Date: Tue, 10 Sep 2024 16:59:12 +0900 Subject: [PATCH] Add post_pass1 stage for import handling --- crates/analyzer/src/analyzer.rs | 4 + crates/analyzer/src/handlers/create_import.rs | 165 ++++++++++++++++++ .../analyzer/src/handlers/create_reference.rs | 86 +-------- .../src/handlers/create_symbol_table.rs | 85 ++++++++- crates/analyzer/src/symbol_table.rs | 43 +++++ crates/analyzer/src/tests.rs | 1 + crates/emitter/src/tests.rs | 1 + crates/languageserver/src/server.rs | 14 +- crates/mdbook/src/main.rs | 1 + crates/tests/benches/benchmark.rs | 3 +- crates/tests/src/lib.rs | 3 + crates/veryl/src/cmd_build.rs | 2 + crates/veryl/src/cmd_check.rs | 2 + crates/veryl/src/cmd_doc.rs | 2 + crates/veryl/src/cmd_dump.rs | 2 + crates/veryl/src/cmd_publish.rs | 2 + 16 files changed, 325 insertions(+), 91 deletions(-) create mode 100644 crates/analyzer/src/handlers/create_import.rs diff --git a/crates/analyzer/src/analyzer.rs b/crates/analyzer/src/analyzer.rs index 1d76b64e..c2a81e60 100644 --- a/crates/analyzer/src/analyzer.rs +++ b/crates/analyzer/src/analyzer.rs @@ -215,6 +215,10 @@ impl Analyzer { ret } + pub fn analyze_post_pass1() { + symbol_table::apply_import(); + } + pub fn analyze_pass2>( &self, project_name: &str, diff --git a/crates/analyzer/src/handlers/create_import.rs b/crates/analyzer/src/handlers/create_import.rs new file mode 100644 index 00000000..082039dd --- /dev/null +++ b/crates/analyzer/src/handlers/create_import.rs @@ -0,0 +1,165 @@ +use crate::analyzer_error::AnalyzerError; +use crate::namespace::Namespace; +use crate::namespace_table; +use crate::symbol::SymbolKind; +use crate::symbol_table::{self, ResolveError, ResolveErrorCause}; +use veryl_parser::resource_table::TokenId; +use veryl_parser::veryl_grammar_trait::*; +use veryl_parser::veryl_token::TokenRange; +use veryl_parser::veryl_walker::{Handler, HandlerPoint}; +use veryl_parser::ParolError; + +#[derive(Default)] +pub struct CreateImport<'a> { + pub errors: Vec, + text: &'a str, + point: HandlerPoint, + top_level: bool, + file_scope_imported_items: Vec, + file_scope_imported_packages: Vec, +} + +impl<'a> CreateImport<'a> { + pub fn new(text: &'a str) -> Self { + Self { + text, + top_level: true, + ..Default::default() + } + } + + fn push_resolve_error(&mut self, err: ResolveError, token: &TokenRange) { + if let Some(last_found) = err.last_found { + let name = last_found.token.to_string(); + match err.cause { + ResolveErrorCause::NotFound(not_found) => { + let member = format!("{}", not_found); + self.errors.push(AnalyzerError::unknown_member( + &name, &member, self.text, token, + )); + } + ResolveErrorCause::Private => { + self.errors + .push(AnalyzerError::private_member(&name, self.text, token)); + } + } + } else if let ResolveErrorCause::NotFound(not_found) = err.cause { + let name = format!("{}", not_found); + self.errors + .push(AnalyzerError::undefined_identifier(&name, self.text, token)); + } else { + unreachable!(); + } + } +} + +impl<'a> Handler for CreateImport<'a> { + fn set_point(&mut self, p: HandlerPoint) { + self.point = p; + } +} + +impl<'a> VerylGrammarTrait for CreateImport<'a> { + fn module_declaration(&mut self, arg: &ModuleDeclaration) -> Result<(), ParolError> { + match self.point { + HandlerPoint::Before => { + self.top_level = false; + let mut namespace = Namespace::default(); + namespace.push(arg.identifier.identifier_token.token.text); + for x in &self.file_scope_imported_items { + symbol_table::add_imported_item(*x, &namespace); + } + for x in &self.file_scope_imported_packages { + symbol_table::add_imported_package(x, &namespace); + } + } + HandlerPoint::After => { + self.top_level = true; + } + } + Ok(()) + } + + fn interface_declaration(&mut self, arg: &InterfaceDeclaration) -> Result<(), ParolError> { + match self.point { + HandlerPoint::Before => { + self.top_level = false; + let mut namespace = Namespace::default(); + namespace.push(arg.identifier.identifier_token.token.text); + for x in &self.file_scope_imported_items { + symbol_table::add_imported_item(*x, &namespace); + } + for x in &self.file_scope_imported_packages { + symbol_table::add_imported_package(x, &namespace); + } + } + HandlerPoint::After => { + self.top_level = true; + } + } + Ok(()) + } + + fn package_declaration(&mut self, arg: &PackageDeclaration) -> Result<(), ParolError> { + match self.point { + HandlerPoint::Before => { + self.top_level = false; + let mut namespace = Namespace::default(); + namespace.push(arg.identifier.identifier_token.token.text); + for x in &self.file_scope_imported_items { + symbol_table::add_imported_item(*x, &namespace); + } + for x in &self.file_scope_imported_packages { + symbol_table::add_imported_package(x, &namespace); + } + } + HandlerPoint::After => { + self.top_level = true; + } + } + Ok(()) + } + + fn import_declaration(&mut self, arg: &ImportDeclaration) -> Result<(), ParolError> { + if let HandlerPoint::Before = self.point { + let is_wildcard = arg.import_declaration_opt.is_some(); + let id = arg.scoped_identifier.identifier().token.id; + let namespace = namespace_table::get(id).unwrap(); + match symbol_table::resolve(arg.scoped_identifier.as_ref()) { + Ok(symbol) => { + let symbol = symbol.found; + match symbol.kind { + SymbolKind::Package(_) if is_wildcard => { + let mut target = symbol.namespace.clone(); + target.push(symbol.token.text); + + if self.top_level { + self.file_scope_imported_packages.push(target); + } else { + symbol_table::add_imported_package(&target, &namespace); + } + } + SymbolKind::SystemVerilog => (), + _ if is_wildcard => { + self.errors.push(AnalyzerError::invalid_import( + self.text, + &arg.scoped_identifier.as_ref().into(), + )); + } + _ => { + if self.top_level { + self.file_scope_imported_items.push(symbol.token.id); + } else { + symbol_table::add_imported_item(symbol.token.id, &namespace); + } + } + } + } + Err(err) => { + self.push_resolve_error(err, &arg.scoped_identifier.as_ref().into()); + } + } + } + Ok(()) + } +} diff --git a/crates/analyzer/src/handlers/create_reference.rs b/crates/analyzer/src/handlers/create_reference.rs index ebc4d896..32c9dc6f 100644 --- a/crates/analyzer/src/handlers/create_reference.rs +++ b/crates/analyzer/src/handlers/create_reference.rs @@ -4,7 +4,6 @@ use crate::namespace_table; use crate::symbol::{GenericMap, SymbolKind}; use crate::symbol_path::{GenericSymbolPath, SymbolPath}; use crate::symbol_table::{self, ResolveError, ResolveErrorCause}; -use veryl_parser::resource_table::TokenId; use veryl_parser::veryl_grammar_trait::*; use veryl_parser::veryl_token::TokenRange; use veryl_parser::veryl_walker::{Handler, HandlerPoint}; @@ -15,16 +14,12 @@ pub struct CreateReference<'a> { pub errors: Vec, text: &'a str, point: HandlerPoint, - top_level: bool, - file_scope_imported_items: Vec, - file_scope_imported_packages: Vec, } impl<'a> CreateReference<'a> { pub fn new(text: &'a str) -> Self { Self { text, - top_level: true, ..Default::default() } } @@ -223,85 +218,14 @@ impl<'a> VerylGrammarTrait for CreateReference<'a> { Ok(()) } - fn module_declaration(&mut self, arg: &ModuleDeclaration) -> Result<(), ParolError> { - match self.point { - HandlerPoint::Before => { - self.top_level = false; - let mut namespace = Namespace::default(); - namespace.push(arg.identifier.identifier_token.token.text); - for x in &self.file_scope_imported_items { - symbol_table::add_imported_item(*x, &namespace); - } - for x in &self.file_scope_imported_packages { - symbol_table::add_imported_package(x, &namespace); - } - } - HandlerPoint::After => { - self.top_level = true; - } - } - Ok(()) - } - - fn interface_declaration(&mut self, arg: &InterfaceDeclaration) -> Result<(), ParolError> { - match self.point { - HandlerPoint::Before => { - self.top_level = false; - let mut namespace = Namespace::default(); - namespace.push(arg.identifier.identifier_token.token.text); - for x in &self.file_scope_imported_items { - symbol_table::add_imported_item(*x, &namespace); - } - for x in &self.file_scope_imported_packages { - symbol_table::add_imported_package(x, &namespace); - } - } - HandlerPoint::After => { - self.top_level = true; - } - } - Ok(()) - } - - fn package_declaration(&mut self, arg: &PackageDeclaration) -> Result<(), ParolError> { - match self.point { - HandlerPoint::Before => { - self.top_level = false; - let mut namespace = Namespace::default(); - namespace.push(arg.identifier.identifier_token.token.text); - for x in &self.file_scope_imported_items { - symbol_table::add_imported_item(*x, &namespace); - } - for x in &self.file_scope_imported_packages { - symbol_table::add_imported_package(x, &namespace); - } - } - HandlerPoint::After => { - self.top_level = true; - } - } - Ok(()) - } - fn import_declaration(&mut self, arg: &ImportDeclaration) -> Result<(), ParolError> { if let HandlerPoint::Before = self.point { let is_wildcard = arg.import_declaration_opt.is_some(); - let id = arg.scoped_identifier.identifier().token.id; - let namespace = namespace_table::get(id).unwrap(); match symbol_table::resolve(arg.scoped_identifier.as_ref()) { Ok(symbol) => { let symbol = symbol.found; match symbol.kind { - SymbolKind::Package(_) if is_wildcard => { - let mut target = symbol.namespace.clone(); - target.push(symbol.token.text); - - if self.top_level { - self.file_scope_imported_packages.push(target); - } else { - symbol_table::add_imported_package(&target, &namespace); - } - } + SymbolKind::Package(_) if is_wildcard => (), SymbolKind::SystemVerilog => (), _ if is_wildcard => { self.errors.push(AnalyzerError::invalid_import( @@ -309,13 +233,7 @@ impl<'a> VerylGrammarTrait for CreateReference<'a> { &arg.scoped_identifier.as_ref().into(), )); } - _ => { - if self.top_level { - self.file_scope_imported_items.push(symbol.token.id); - } else { - symbol_table::add_imported_item(symbol.token.id, &namespace); - } - } + _ => (), } } Err(err) => { diff --git a/crates/analyzer/src/handlers/create_symbol_table.rs b/crates/analyzer/src/handlers/create_symbol_table.rs index 832a79d8..06a1d488 100644 --- a/crates/analyzer/src/handlers/create_symbol_table.rs +++ b/crates/analyzer/src/handlers/create_symbol_table.rs @@ -19,8 +19,9 @@ use crate::symbol::{ SymbolKind, TestProperty, TestType, TypeDefProperty, TypeKind, UnionMemberProperty, UnionProperty, VariableAffiniation, VariableProperty, }; -use crate::symbol_path::{GenericSymbolPath, SymbolPath}; +use crate::symbol_path::{GenericSymbolPath, SymbolPath, SymbolPathNamespace}; use crate::symbol_table; +use crate::symbol_table::Import as SymImport; use std::collections::{HashMap, HashSet}; use veryl_metadata::ClockType; use veryl_metadata::{Build, ResetType}; @@ -64,6 +65,8 @@ pub struct CreateSymbolTable<'a> { function_ids: HashMap, exist_clock_without_domain: bool, in_proto: bool, + file_scope_import_item: Vec, + file_scope_import_wildcard: Vec, } #[derive(Clone)] @@ -1088,6 +1091,32 @@ impl<'a> VerylGrammarTrait for CreateSymbolTable<'a> { Ok(()) } + fn import_declaration(&mut self, arg: &ImportDeclaration) -> Result<(), ParolError> { + if let HandlerPoint::Before = self.point { + let path: SymbolPath = arg.scoped_identifier.as_ref().into(); + let path: SymbolPathNamespace = (&path, &self.namespace).into(); + let namespace = path.1.clone(); + let wildcard = arg.import_declaration_opt.is_some(); + + let import = SymImport { + path: path.clone(), + namespace, + wildcard, + }; + + if self.affiniation.is_empty() { + if wildcard { + self.file_scope_import_wildcard.push(path); + } else { + self.file_scope_import_item.push(path); + } + } else { + symbol_table::add_import(import); + } + } + Ok(()) + } + fn module_declaration(&mut self, arg: &ModuleDeclaration) -> Result<(), ParolError> { let name = arg.identifier.identifier_token.token.text; match self.point { @@ -1100,6 +1129,24 @@ impl<'a> VerylGrammarTrait for CreateSymbolTable<'a> { self.module_namspace_depth = self.namespace.depth(); self.function_ids.clear(); self.exist_clock_without_domain = false; + + for x in &self.file_scope_import_item { + let import = SymImport { + path: x.clone(), + namespace: self.namespace.clone(), + wildcard: false, + }; + symbol_table::add_import(import); + } + + for x in &self.file_scope_import_wildcard { + let import = SymImport { + path: x.clone(), + namespace: self.namespace.clone(), + wildcard: true, + }; + symbol_table::add_import(import); + } } HandlerPoint::After => { self.namespace.pop(); @@ -1227,6 +1274,24 @@ impl<'a> VerylGrammarTrait for CreateSymbolTable<'a> { self.affiniation.push(VariableAffiniation::Intarface); self.function_ids.clear(); self.modport_member_ids.clear(); + + for x in &self.file_scope_import_item { + let import = SymImport { + path: x.clone(), + namespace: self.namespace.clone(), + wildcard: false, + }; + symbol_table::add_import(import); + } + + for x in &self.file_scope_import_wildcard { + let import = SymImport { + path: x.clone(), + namespace: self.namespace.clone(), + wildcard: true, + }; + symbol_table::add_import(import); + } } HandlerPoint::After => { self.namespace.pop(); @@ -1277,6 +1342,24 @@ impl<'a> VerylGrammarTrait for CreateSymbolTable<'a> { self.generic_parameters.push(Vec::new()); self.affiniation.push(VariableAffiniation::Package); self.function_ids.clear(); + + for x in &self.file_scope_import_item { + let import = SymImport { + path: x.clone(), + namespace: self.namespace.clone(), + wildcard: false, + }; + symbol_table::add_import(import); + } + + for x in &self.file_scope_import_wildcard { + let import = SymImport { + path: x.clone(), + namespace: self.namespace.clone(), + wildcard: true, + }; + symbol_table::add_import(import); + } } HandlerPoint::After => { self.namespace.pop(); diff --git a/crates/analyzer/src/symbol_table.rs b/crates/analyzer/src/symbol_table.rs index 987a39d9..9fd92986 100644 --- a/crates/analyzer/src/symbol_table.rs +++ b/crates/analyzer/src/symbol_table.rs @@ -36,12 +36,20 @@ impl ResolveError { } } +#[derive(Clone, Debug)] +pub struct Import { + pub path: SymbolPathNamespace, + pub namespace: Namespace, + pub wildcard: bool, +} + #[derive(Clone, Default, Debug)] pub struct SymbolTable { name_table: HashMap>, symbol_table: HashMap, project_local_table: HashMap>, assign_list: Vec, + import_list: Vec, } impl SymbolTable { @@ -396,6 +404,33 @@ impl SymbolTable { } } + pub fn add_import(&mut self, import: Import) { + self.import_list.push(import); + } + + pub fn apply_import(&mut self) { + let import_list: Vec<_> = self.import_list.drain(0..).collect(); + for import in import_list { + if let Ok(symbol) = self.resolve(&import.path.0, &import.path.1) { + let symbol = symbol.found; + match symbol.kind { + SymbolKind::Package(_) if import.wildcard => { + let mut target = symbol.namespace.clone(); + target.push(symbol.token.text); + + self.add_imported_package(&target, &import.namespace); + } + SymbolKind::SystemVerilog => (), + // Error will be reported at create_reference + _ if import.wildcard => (), + _ => { + self.add_imported_item(symbol.token.id, &import.namespace); + } + } + } + } + } + pub fn add_project_local(&mut self, prj: StrId, from: StrId, to: StrId) { self.project_local_table .entry(prj) @@ -1019,6 +1054,14 @@ pub fn add_imported_package(target: &Namespace, namespace: &Namespace) { SYMBOL_TABLE.with(|f| f.borrow_mut().add_imported_package(target, namespace)) } +pub fn add_import(import: Import) { + SYMBOL_TABLE.with(|f| f.borrow_mut().add_import(import)) +} + +pub fn apply_import() { + SYMBOL_TABLE.with(|f| f.borrow_mut().apply_import()) +} + pub fn add_project_local(prj: StrId, from: StrId, to: StrId) { SYMBOL_TABLE.with(|f| f.borrow_mut().add_project_local(prj, from, to)) } diff --git a/crates/analyzer/src/tests.rs b/crates/analyzer/src/tests.rs index 188752d8..02b8bb02 100644 --- a/crates/analyzer/src/tests.rs +++ b/crates/analyzer/src/tests.rs @@ -13,6 +13,7 @@ fn analyze(code: &str) -> Vec { let mut errors = vec![]; errors.append(&mut analyzer.analyze_pass1(&"prj", &code, &"", &parser.veryl)); + Analyzer::analyze_post_pass1(); errors.append(&mut analyzer.analyze_pass2(&"prj", &code, &"", &parser.veryl)); errors.append(&mut analyzer.analyze_pass3(&"prj", &code, &"", &parser.veryl)); dbg!(&errors); diff --git a/crates/emitter/src/tests.rs b/crates/emitter/src/tests.rs index fb4f3e86..04a53885 100644 --- a/crates/emitter/src/tests.rs +++ b/crates/emitter/src/tests.rs @@ -11,6 +11,7 @@ fn emit(metadata: &Metadata, code: &str) -> String { analyzer.analyze_pass1(&"prj", &code, &"", &parser.veryl); analyzer.analyze_pass2(&"prj", &code, &"", &parser.veryl); + analyzer.analyze_pass3(&"prj", &code, &"", &parser.veryl); let mut emitter = Emitter::new( metadata, diff --git a/crates/languageserver/src/server.rs b/crates/languageserver/src/server.rs index b2317592..91b0a0c9 100644 --- a/crates/languageserver/src/server.rs +++ b/crates/languageserver/src/server.rs @@ -176,7 +176,9 @@ impl Server { pcnt as u32, ); } + if task.paths.is_empty() { + Analyzer::analyze_post_pass1(); self.progress_done("background analyze done"); if self.background_tasks.is_empty() { self.background_done = true; @@ -598,6 +600,7 @@ impl Server { if self.document_map.contains_key(&src) { return; } + if let Ok(x) = Parser::parse(&text, &src) { if let Some(src) = resource_table::get_path_id(&src) { symbol_table::drop(src); @@ -605,12 +608,12 @@ impl Server { } let analyzer = Analyzer::new(metadata); let _ = analyzer.analyze_pass1(&path.prj, &text, &src, &x.veryl); - - block_on(self.client.log_message( - MessageType::INFO, - format!("background_analyze: {}", src.to_string_lossy()), - )); } + + block_on(self.client.log_message( + MessageType::INFO, + format!("background_analyze: {}", src.to_string_lossy()), + )); } } @@ -647,6 +650,7 @@ impl Server { } let analyzer = Analyzer::new(&metadata); let mut errors = analyzer.analyze_pass1(prj, text, &path, &x.veryl); + Analyzer::analyze_post_pass1(); errors.append(&mut analyzer.analyze_pass2(prj, text, &path, &x.veryl)); errors.append(&mut analyzer.analyze_pass3(prj, text, &path, &x.veryl)); let ret: Vec<_> = errors diff --git a/crates/mdbook/src/main.rs b/crates/mdbook/src/main.rs index 4165ee1f..8e8dc584 100644 --- a/crates/mdbook/src/main.rs +++ b/crates/mdbook/src/main.rs @@ -164,6 +164,7 @@ impl Preprocessor for Veryl { errors.append( &mut analyzer.analyze_pass1(prj, &x, "", &ret.veryl), ); + Analyzer::analyze_post_pass1(); errors.append( &mut analyzer.analyze_pass2(prj, &x, "", &ret.veryl), ); diff --git a/crates/tests/benches/benchmark.rs b/crates/tests/benches/benchmark.rs index 5a01bfb0..c904d55c 100644 --- a/crates/tests/benches/benchmark.rs +++ b/crates/tests/benches/benchmark.rs @@ -35,7 +35,8 @@ fn criterion_benchmark(c: &mut Criterion) { let analyzer = Analyzer::new(black_box(&metadata)); analyzer.analyze_pass1(prj, black_box(&text), &"", &parser.veryl); analyzer.analyze_pass2(prj, black_box(&text), &"", &parser.veryl); - //analyzer.analyze_pass3(prj, black_box(&text), &"", &parser.veryl); + analyzer.analyze_pass3(prj, black_box(&text), &"", &parser.veryl); + //analyzer.analyze_pass4(prj, black_box(&text), &"", &parser.veryl); }) }); group.bench_function("format", |b| { diff --git a/crates/tests/src/lib.rs b/crates/tests/src/lib.rs index 47b4682d..48649ae6 100644 --- a/crates/tests/src/lib.rs +++ b/crates/tests/src/lib.rs @@ -53,6 +53,8 @@ mod analyzer { dbg!(&errors); assert!(errors.is_empty()); + Analyzer::analyze_post_pass1(); + let errors = analyzer.analyze_pass2(&prj, &input, &file, &ret.veryl); dbg!(&errors); assert!(errors.is_empty()); @@ -135,6 +137,7 @@ mod emitter { let prj = &metadata.project.name; let analyzer = Analyzer::new(&metadata); let _ = analyzer.analyze_pass1(&prj, &input, &src_path, &ret.veryl); + Analyzer::analyze_post_pass1(); let _ = analyzer.analyze_pass2(&prj, &input, &src_path, &ret.veryl); let mut emitter = Emitter::new(&metadata, &src_path, &dst_path, &map_path); emitter.emit(&prj, &ret.veryl); diff --git a/crates/veryl/src/cmd_build.rs b/crates/veryl/src/cmd_build.rs index 6ea01a31..232ede06 100644 --- a/crates/veryl/src/cmd_build.rs +++ b/crates/veryl/src/cmd_build.rs @@ -46,6 +46,8 @@ impl CmdBuild { contexts.push((path, input, parser, analyzer)); } + Analyzer::analyze_post_pass1(); + for (path, input, parser, analyzer) in &contexts { let mut errors = analyzer.analyze_pass2(&path.prj, input, &path.src, &parser.veryl); check_error = check_error.append(&mut errors).check_err()?; diff --git a/crates/veryl/src/cmd_check.rs b/crates/veryl/src/cmd_check.rs index b69da1f6..ae66bacf 100644 --- a/crates/veryl/src/cmd_check.rs +++ b/crates/veryl/src/cmd_check.rs @@ -71,6 +71,8 @@ impl CmdCheck { contexts.push((path, input, parser, analyzer)); } + Analyzer::analyze_post_pass1(); + for (path, input, parser, analyzer) in &contexts { let mut errors = analyzer.analyze_pass2(&path.prj, input, &path.src, &parser.veryl); check_error = check_error.append(&mut errors).check_err()?; diff --git a/crates/veryl/src/cmd_doc.rs b/crates/veryl/src/cmd_doc.rs index b32c886c..583141c9 100644 --- a/crates/veryl/src/cmd_doc.rs +++ b/crates/veryl/src/cmd_doc.rs @@ -37,6 +37,8 @@ impl CmdDoc { contexts.push((path, input, parser, analyzer)); } + Analyzer::analyze_post_pass1(); + for (path, input, parser, analyzer) in &contexts { analyzer.analyze_pass2(&path.prj, input, &path.src, &parser.veryl); } diff --git a/crates/veryl/src/cmd_dump.rs b/crates/veryl/src/cmd_dump.rs index f3c4bc3d..41479dfb 100644 --- a/crates/veryl/src/cmd_dump.rs +++ b/crates/veryl/src/cmd_dump.rs @@ -33,6 +33,8 @@ impl CmdDump { contexts.push((path, input, parser, analyzer)); } + Analyzer::analyze_post_pass1(); + for (path, input, parser, analyzer) in &contexts { analyzer.analyze_pass2(&path.prj, input, &path.src, &parser.veryl); } diff --git a/crates/veryl/src/cmd_publish.rs b/crates/veryl/src/cmd_publish.rs index 12a64782..494209b2 100644 --- a/crates/veryl/src/cmd_publish.rs +++ b/crates/veryl/src/cmd_publish.rs @@ -47,6 +47,8 @@ impl CmdPublish { contexts.push((path, input, parser, analyzer)); } + Analyzer::analyze_post_pass1(); + for (path, input, parser, analyzer) in &contexts { let mut errors = analyzer.analyze_pass2(&path.prj, input, &path.src, &parser.veryl); check_error = check_error.append(&mut errors).check_err()?;