Skip to content

Commit 306c891

Browse files
authored
Merge pull request #3103 from taichi-ishitani/fix_undefined_identifier
Resolve reference to import items as priority
2 parents 5893f97 + 4871a00 commit 306c891

2 files changed

Lines changed: 85 additions & 12 deletions

File tree

crates/analyzer/src/handlers/create_symbol_table.rs

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ pub struct CreateSymbolTable {
111111
in_expression_identifier: Vec<()>,
112112
in_select: bool,
113113
reference_functions: Vec<GenericSymbolPath>,
114+
reference_candidates: Vec<Vec<ReferenceCandidate>>,
114115
}
115116

116117
#[derive(Clone)]
@@ -464,6 +465,38 @@ impl CreateSymbolTable {
464465
fn is_in_expression_identifier(&self) -> bool {
465466
!self.in_expression_identifier.is_empty()
466467
}
468+
469+
fn add_reference_candidate(&mut self, candidate: ReferenceCandidate) {
470+
if let Some(candidates) = self.reference_candidates.last_mut() {
471+
candidates.push(candidate);
472+
} else {
473+
reference_table::add(candidate);
474+
}
475+
}
476+
477+
fn pop_reference_candidates(&mut self) {
478+
fn is_import_item(candidate: &ReferenceCandidate) -> bool {
479+
match candidate {
480+
ReferenceCandidate::ScopedIdentifier {
481+
in_import_declaration,
482+
..
483+
} => *in_import_declaration,
484+
ReferenceCandidate::ImportItem { .. } => true,
485+
_ => false,
486+
}
487+
}
488+
489+
if let Some(candidates) = self.reference_candidates.pop() {
490+
let (import_items, other_itesm): (Vec<_>, Vec<_>) =
491+
candidates.into_iter().partition(is_import_item);
492+
for item in import_items {
493+
reference_table::add(item);
494+
}
495+
for item in other_itesm {
496+
reference_table::add(item);
497+
}
498+
}
499+
}
467500
}
468501

469502
impl Handler for CreateSymbolTable {
@@ -552,7 +585,7 @@ impl VerylGrammarTrait for CreateSymbolTable {
552585

553586
fn hierarchical_identifier(&mut self, arg: &HierarchicalIdentifier) -> Result<(), ParolError> {
554587
if let HandlerPoint::Before = self.point {
555-
reference_table::add(arg.into());
588+
self.add_reference_candidate(arg.into());
556589
}
557590

558591
Ok(())
@@ -561,7 +594,7 @@ impl VerylGrammarTrait for CreateSymbolTable {
561594
fn scoped_identifier(&mut self, arg: &ScopedIdentifier) -> Result<(), ParolError> {
562595
if let HandlerPoint::Before = self.point {
563596
if !self.with_member_reference {
564-
reference_table::add((arg, self.in_import).into());
597+
self.add_reference_candidate((arg, self.in_import).into());
565598
}
566599

567600
// Add symbols under $sv namespace
@@ -620,9 +653,9 @@ impl VerylGrammarTrait for CreateSymbolTable {
620653
arg: arg.clone(),
621654
function,
622655
};
623-
reference_table::add(cand);
656+
self.add_reference_candidate(cand);
624657
} else {
625-
reference_table::add(arg.into());
658+
self.add_reference_candidate(arg.into());
626659
}
627660

628661
self.identifier_path.push(SymbolPathNamespace::default());
@@ -649,7 +682,7 @@ impl VerylGrammarTrait for CreateSymbolTable {
649682
match self.point {
650683
HandlerPoint::Before => {
651684
self.with_member_reference = true;
652-
reference_table::add(arg.into());
685+
self.add_reference_candidate(arg.into());
653686
}
654687
HandlerPoint::After => self.with_member_reference = false,
655688
}
@@ -738,7 +771,7 @@ impl VerylGrammarTrait for CreateSymbolTable {
738771
arg: arg.clone(),
739772
r#type: self.identifier_factor_names.last().unwrap().clone(),
740773
};
741-
reference_table::add(cand);
774+
self.add_reference_candidate(cand);
742775
}
743776
Ok(())
744777
}
@@ -1133,7 +1166,7 @@ impl VerylGrammarTrait for CreateSymbolTable {
11331166
ModportDefault::SameLParenModportDefaultListRParen(x) => {
11341167
let targets: Vec<_> = x.modport_default_list.as_ref().into();
11351168
for target in &targets {
1136-
reference_table::add((*target).into());
1169+
self.add_reference_candidate((*target).into());
11371170
}
11381171

11391172
let modports: Vec<_> =
@@ -1143,7 +1176,7 @@ impl VerylGrammarTrait for CreateSymbolTable {
11431176
ModportDefault::ConverseLParenModportDefaultListRParen(x) => {
11441177
let targets: Vec<_> = x.modport_default_list.as_ref().into();
11451178
for target in &targets {
1146-
reference_table::add((*target).into());
1179+
self.add_reference_candidate((*target).into());
11471180
}
11481181

11491182
let modports: Vec<_> =
@@ -1177,7 +1210,7 @@ impl VerylGrammarTrait for CreateSymbolTable {
11771210

11781211
fn modport_item(&mut self, arg: &ModportItem) -> Result<(), ParolError> {
11791212
if let HandlerPoint::Before = self.point {
1180-
reference_table::add(arg.into());
1213+
self.add_reference_candidate(arg.into());
11811214
}
11821215
Ok(())
11831216
}
@@ -1492,7 +1525,7 @@ impl VerylGrammarTrait for CreateSymbolTable {
14921525
fn inst_parameter_item(&mut self, arg: &InstParameterItem) -> Result<(), ParolError> {
14931526
match self.point {
14941527
HandlerPoint::Before => {
1495-
reference_table::add(arg.into());
1528+
self.add_reference_candidate(arg.into());
14961529
self.connect_target_identifiers.clear();
14971530
}
14981531
HandlerPoint::After => {
@@ -1522,7 +1555,7 @@ impl VerylGrammarTrait for CreateSymbolTable {
15221555
fn inst_port_item(&mut self, arg: &InstPortItem) -> Result<(), ParolError> {
15231556
match self.point {
15241557
HandlerPoint::Before => {
1525-
reference_table::add(arg.into());
1558+
self.add_reference_candidate(arg.into());
15261559
self.connect_target_identifiers.clear();
15271560
}
15281561
HandlerPoint::After => {
@@ -1880,7 +1913,9 @@ impl VerylGrammarTrait for CreateSymbolTable {
18801913
ImportDeclarationOptGroup::MultipleImportList(x) => {
18811914
let item_list: Vec<_> = x.multiple_import_list.as_ref().into();
18821915
for x in item_list {
1883-
reference_table::add((arg.scoped_identifier.as_ref(), x).into());
1916+
self.add_reference_candidate(
1917+
(arg.scoped_identifier.as_ref(), x).into(),
1918+
);
18841919

18851920
let mut item_path = path.clone();
18861921
item_path
@@ -1927,6 +1962,7 @@ impl VerylGrammarTrait for CreateSymbolTable {
19271962
self.parameters.push(Vec::new());
19281963
self.ports.push(Vec::new());
19291964
self.affiliation.push(Affiliation::Module);
1965+
self.reference_candidates.push(Vec::new());
19301966
self.module_namspace_depth = scope::depth(scope::current());
19311967
self.exist_clock_without_domain = false;
19321968

@@ -1941,6 +1977,7 @@ impl VerylGrammarTrait for CreateSymbolTable {
19411977
let (generic_parameters, generic_consts) = self.generic_context.pop();
19421978
let parameters: Vec<_> = self.parameters.pop().unwrap();
19431979
let ports: Vec<_> = self.ports.pop().unwrap();
1980+
self.pop_reference_candidates();
19441981

19451982
let default_clock = if self.default_clock.is_some() {
19461983
self.default_clock
@@ -2103,12 +2140,14 @@ impl VerylGrammarTrait for CreateSymbolTable {
21032140
self.generic_context.push();
21042141
self.parameters.push(Vec::new());
21052142
self.affiliation.push(Affiliation::Interface);
2143+
self.reference_candidates.push(Vec::new());
21062144
self.apply_file_scope_import();
21072145
self.push_type_dag_cand();
21082146
}
21092147
HandlerPoint::After => {
21102148
self.pop_namespace();
21112149
self.affiliation.pop();
2150+
self.pop_reference_candidates();
21122151

21132152
let (generic_parameters, generic_consts) = self.generic_context.pop();
21142153
let mixin_sources: Vec<_> = self.mixin_sources.drain(..).collect();
@@ -2161,12 +2200,14 @@ impl VerylGrammarTrait for CreateSymbolTable {
21612200
self.push_namespace(name);
21622201
self.generic_context.push();
21632202
self.affiliation.push(Affiliation::Package);
2203+
self.reference_candidates.push(Vec::new());
21642204
self.apply_file_scope_import();
21652205
self.push_type_dag_cand();
21662206
}
21672207
HandlerPoint::After => {
21682208
self.pop_namespace();
21692209
self.affiliation.pop();
2210+
self.pop_reference_candidates();
21702211

21712212
let (generic_parameters, generic_consts) = self.generic_context.pop();
21722213

@@ -2264,10 +2305,12 @@ impl VerylGrammarTrait for CreateSymbolTable {
22642305
self.in_proto = true;
22652306
self.parameters.push(Vec::new());
22662307
self.ports.push(Vec::new());
2308+
self.reference_candidates.push(Vec::new());
22672309
}
22682310
HandlerPoint::After => {
22692311
self.pop_namespace();
22702312
self.affiliation.pop();
2313+
self.pop_reference_candidates();
22712314
self.in_proto = false;
22722315

22732316
let parameters: Vec<_> = self.parameters.pop().unwrap();
@@ -2307,11 +2350,13 @@ impl VerylGrammarTrait for CreateSymbolTable {
23072350
self.push_namespace(arg.identifier.text());
23082351
self.affiliation.push(Affiliation::Interface);
23092352
self.parameters.push(Vec::new());
2353+
self.reference_candidates.push(Vec::new());
23102354
self.apply_file_scope_import();
23112355
}
23122356
HandlerPoint::After => {
23132357
self.pop_namespace();
23142358
self.affiliation.pop();
2359+
self.pop_reference_candidates();
23152360

23162361
let parameters: Vec<_> = self.parameters.pop().unwrap();
23172362
let property = InterfaceProperty {
@@ -2344,11 +2389,13 @@ impl VerylGrammarTrait for CreateSymbolTable {
23442389
HandlerPoint::Before => {
23452390
self.push_namespace(arg.identifier.text());
23462391
self.affiliation.push(Affiliation::Package);
2392+
self.reference_candidates.push(Vec::new());
23472393
self.apply_file_scope_import();
23482394
}
23492395
HandlerPoint::After => {
23502396
self.pop_namespace();
23512397
self.affiliation.pop();
2398+
self.pop_reference_candidates();
23522399

23532400
let property = PackageProperty {
23542401
range: arg.into(),

crates/analyzer/src/tests.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6523,6 +6523,32 @@ fn undefined_identifier() {
65236523

65246524
let errors = analyze(code);
65256525
assert!(errors.is_empty());
6526+
6527+
let inputs = vec![
6528+
r#"
6529+
package a_pkg {
6530+
const WIDTH: u32 = 32;
6531+
}
6532+
"#,
6533+
r#"
6534+
package b_pkg::<W: u32> {
6535+
type T = logic<W>;
6536+
const B: T = 0;
6537+
}
6538+
"#,
6539+
r#"
6540+
module c_module (
6541+
c: output T,
6542+
) {
6543+
import a_pkg::*;
6544+
import b_pkg::<WIDTH>::{T, B};
6545+
assign c = B;
6546+
}
6547+
"#,
6548+
];
6549+
6550+
let errors = analyze_multiple_inputs(&inputs);
6551+
assert!(errors.is_empty());
65266552
}
65276553

65286554
#[test]

0 commit comments

Comments
 (0)