Skip to content

Commit f996118

Browse files
committed
Resolve SymbolId of user defined types after pass1
1 parent 08d1266 commit f996118

File tree

6 files changed

+108
-55
lines changed

6 files changed

+108
-55
lines changed

crates/analyzer/src/analyzer.rs

+15-14
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ impl Analyzer {
281281

282282
pub fn analyze_post_pass1() {
283283
symbol_table::apply_import();
284+
symbol_table::resolve_user_defined();
284285
}
285286

286287
pub fn analyze_pass2<T: AsRef<Path>>(
@@ -349,35 +350,35 @@ fn traverse_type_symbol(id: SymbolId, path: &VarRefPath) -> Vec<VarRefPath> {
349350
match &symbol.kind {
350351
SymbolKind::Variable(x) => {
351352
if let TypeKind::UserDefined(ref x) = x.r#type.kind {
352-
if let Ok(symbol) = symbol_table::resolve((x, &symbol.namespace)) {
353-
return traverse_type_symbol(symbol.found.id, path);
353+
if let Some(id) = x.symbol {
354+
return traverse_type_symbol(id, path);
354355
}
355356
} else {
356357
return vec![path.clone()];
357358
}
358359
}
359360
SymbolKind::StructMember(x) => {
360361
if let TypeKind::UserDefined(ref x) = x.r#type.kind {
361-
if let Ok(symbol) = symbol_table::resolve((x, &symbol.namespace)) {
362-
return traverse_type_symbol(symbol.found.id, path);
362+
if let Some(id) = x.symbol {
363+
return traverse_type_symbol(id, path);
363364
}
364365
} else {
365366
return vec![path.clone()];
366367
}
367368
}
368369
SymbolKind::UnionMember(x) => {
369370
if let TypeKind::UserDefined(ref x) = x.r#type.kind {
370-
if let Ok(symbol) = symbol_table::resolve((x, &symbol.namespace)) {
371-
return traverse_type_symbol(symbol.found.id, path);
371+
if let Some(id) = x.symbol {
372+
return traverse_type_symbol(id, path);
372373
}
373374
} else {
374375
return vec![path.clone()];
375376
}
376377
}
377378
SymbolKind::TypeDef(x) => {
378379
if let TypeKind::UserDefined(ref x) = x.r#type.kind {
379-
if let Ok(symbol) = symbol_table::resolve((x, &symbol.namespace)) {
380-
return traverse_type_symbol(symbol.found.id, path);
380+
if let Some(id) = x.symbol {
381+
return traverse_type_symbol(id, path);
381382
}
382383
} else {
383384
return vec![path.clone()];
@@ -387,8 +388,8 @@ fn traverse_type_symbol(id: SymbolId, path: &VarRefPath) -> Vec<VarRefPath> {
387388
let r#type: Result<crate::symbol::Type, ()> = (&x.value).try_into();
388389
if let Ok(r#type) = r#type {
389390
if let TypeKind::UserDefined(ref x) = r#type.kind {
390-
if let Ok(symbol) = symbol_table::resolve((x, &symbol.namespace)) {
391-
return traverse_type_symbol(symbol.found.id, path);
391+
if let Some(id) = x.symbol {
392+
return traverse_type_symbol(id, path);
392393
}
393394
} else {
394395
return vec![path.clone()];
@@ -451,8 +452,8 @@ fn traverse_assignable_symbol(id: SymbolId, path: &VarRefPath) -> Vec<VarRefPath
451452
SymbolKind::Port(x) if is_assignable(&x.direction) && !x.is_proto => {
452453
if let Some(ref x) = x.r#type {
453454
if let TypeKind::UserDefined(ref x) = x.kind {
454-
if let Ok(symbol) = symbol_table::resolve((x, &symbol.namespace)) {
455-
return traverse_type_symbol(symbol.found.id, path);
455+
if let Some(id) = x.symbol {
456+
return traverse_type_symbol(id, path);
456457
}
457458
} else {
458459
return vec![path.clone()];
@@ -465,8 +466,8 @@ fn traverse_assignable_symbol(id: SymbolId, path: &VarRefPath) -> Vec<VarRefPath
465466
|| x.affiliation == VariableAffiliation::StatementBlock =>
466467
{
467468
if let TypeKind::UserDefined(ref x) = x.r#type.kind {
468-
if let Ok(symbol) = symbol_table::resolve((x, &symbol.namespace)) {
469-
return traverse_type_symbol(symbol.found.id, path);
469+
if let Some(id) = x.symbol {
470+
return traverse_type_symbol(id, path);
470471
}
471472
} else {
472473
return vec![path.clone()];

crates/analyzer/src/handlers/check_msb_lsb.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::analyzer_error::AnalyzerError;
22
use crate::msb_table;
3-
use crate::namespace::Namespace;
43
use crate::namespace_table;
54
use crate::symbol::Type as SymType;
65
use crate::symbol::{Direction, SymbolKind, TypeKind};
@@ -40,13 +39,14 @@ impl Handler for CheckMsbLsb<'_> {
4039
}
4140
}
4241

43-
fn trace_type(r#type: &SymType, namespace: &Namespace) -> Vec<(SymType, Option<SymbolKind>)> {
42+
fn trace_type(r#type: &SymType) -> Vec<(SymType, Option<SymbolKind>)> {
4443
let mut ret = vec![(r#type.clone(), None)];
4544
if let TypeKind::UserDefined(ref x) = r#type.kind {
46-
if let Ok(symbol) = symbol_table::resolve((&SymbolPath::new(x), namespace)) {
47-
ret.last_mut().unwrap().1 = Some(symbol.found.kind.clone());
48-
if let SymbolKind::TypeDef(ref x) = symbol.found.kind {
49-
ret.append(&mut trace_type(&x.r#type, namespace));
45+
if let Some(id) = x.symbol {
46+
let symbol = symbol_table::get(id).unwrap();
47+
ret.last_mut().unwrap().1 = Some(symbol.kind.clone());
48+
if let SymbolKind::TypeDef(ref x) = symbol.kind {
49+
ret.append(&mut trace_type(&x.r#type));
5050
}
5151
}
5252
}
@@ -72,8 +72,6 @@ impl VerylGrammarTrait for CheckMsbLsb<'_> {
7272
let resolved = if let Ok(x) =
7373
symbol_table::resolve(self.identifier_path.last().unwrap().clone())
7474
{
75-
let namespace = &x.found.namespace;
76-
7775
let via_interface = x.full_path.iter().any(|path| {
7876
let symbol = symbol_table::get(*path).unwrap();
7977
match symbol.kind {
@@ -98,7 +96,7 @@ impl VerylGrammarTrait for CheckMsbLsb<'_> {
9896
};
9997

10098
if let Some(x) = r#type {
101-
let types = trace_type(&x, namespace);
99+
let types = trace_type(&x);
102100
let mut select_dimension = *self.select_dimension.last().unwrap();
103101

104102
let mut demension_number = None;

crates/analyzer/src/handlers/create_symbol_table.rs

+3-18
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use crate::evaluator::Evaluated;
66
use crate::evaluator::Evaluator;
77
use crate::namespace::Namespace;
88
use crate::namespace_table;
9-
use crate::symbol;
109
use crate::symbol::ClockDomain as SymClockDomain;
1110
use crate::symbol::Direction as SymDirection;
1211
use crate::symbol::Type as SymType;
@@ -116,16 +115,6 @@ impl<'a> CreateSymbolTable<'a> {
116115
}
117116

118117
fn insert_symbol(&mut self, token: &Token, kind: SymbolKind, public: bool) -> Option<SymbolId> {
119-
self.insert_symbol_with_type(token, kind, public, None)
120-
}
121-
122-
fn insert_symbol_with_type(
123-
&mut self,
124-
token: &Token,
125-
kind: SymbolKind,
126-
public: bool,
127-
r#type: Option<symbol::Type>,
128-
) -> Option<SymbolId> {
129118
let line = token.line;
130119
let doc_comment = if let TokenSource::File(file) = token.source {
131120
if line == 0 {
@@ -157,7 +146,6 @@ impl<'a> CreateSymbolTable<'a> {
157146
symbol.allow_unused = true;
158147
}
159148

160-
symbol.r#type = r#type;
161149
let id = symbol_table::insert(token, symbol);
162150
if id.is_none() {
163151
self.errors.push(AnalyzerError::duplicated_identifier(
@@ -590,12 +578,9 @@ impl VerylGrammarTrait for CreateSymbolTable<'_> {
590578
};
591579
let kind = SymbolKind::Variable(property);
592580

593-
if let Some(id) = self.insert_symbol_with_type(
594-
&arg.identifier.identifier_token.token,
595-
kind.clone(),
596-
false,
597-
None,
598-
) {
581+
if let Some(id) =
582+
self.insert_symbol(&arg.identifier.identifier_token.token, kind.clone(), false)
583+
{
599584
if self.is_default_clock_candidate(kind.clone()) {
600585
self.default_clock_candidates.push(id);
601586
} else if self.is_default_reset_candidate(kind.clone()) {

crates/analyzer/src/symbol.rs

+44-8
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ pub struct Symbol {
7272
pub allow_unused: bool,
7373
pub public: bool,
7474
pub doc_comment: DocComment,
75-
pub r#type: Option<Type>,
7675
}
7776

7877
impl Symbol {
@@ -95,7 +94,6 @@ impl Symbol {
9594
allow_unused: false,
9695
public,
9796
doc_comment,
98-
r#type: None,
9997
}
10098
}
10199

@@ -428,6 +426,32 @@ impl SymbolKind {
428426
_ => None,
429427
}
430428
}
429+
430+
pub fn get_type(&self) -> Option<&Type> {
431+
match self {
432+
SymbolKind::Port(x) => x.r#type.as_ref(),
433+
SymbolKind::Variable(x) => Some(&x.r#type),
434+
SymbolKind::Function(x) => x.ret.as_ref(),
435+
SymbolKind::Parameter(x) => Some(&x.r#type),
436+
SymbolKind::StructMember(x) => Some(&x.r#type),
437+
SymbolKind::UnionMember(x) => Some(&x.r#type),
438+
SymbolKind::TypeDef(x) => Some(&x.r#type),
439+
_ => None,
440+
}
441+
}
442+
443+
pub fn get_type_mut(&mut self) -> Option<&mut Type> {
444+
match self {
445+
SymbolKind::Port(x) => x.r#type.as_mut(),
446+
SymbolKind::Variable(x) => Some(&mut x.r#type),
447+
SymbolKind::Function(x) => x.ret.as_mut(),
448+
SymbolKind::Parameter(x) => Some(&mut x.r#type),
449+
SymbolKind::StructMember(x) => Some(&mut x.r#type),
450+
SymbolKind::UnionMember(x) => Some(&mut x.r#type),
451+
SymbolKind::TypeDef(x) => Some(&mut x.r#type),
452+
_ => None,
453+
}
454+
}
431455
}
432456

433457
impl fmt::Display for SymbolKind {
@@ -608,7 +632,7 @@ pub enum TypeKind {
608632
F64,
609633
Type,
610634
String,
611-
UserDefined(Vec<StrId>),
635+
UserDefined(UserDefinedType),
612636
}
613637

614638
impl TypeKind {
@@ -631,6 +655,18 @@ impl TypeKind {
631655
}
632656
}
633657

658+
#[derive(Debug, Clone, PartialEq, Eq)]
659+
pub struct UserDefinedType {
660+
pub path: Vec<StrId>,
661+
pub symbol: Option<SymbolId>,
662+
}
663+
664+
impl UserDefinedType {
665+
fn new(path: Vec<StrId>) -> Self {
666+
Self { path, symbol: None }
667+
}
668+
}
669+
634670
#[derive(Debug, Clone, PartialEq, Eq)]
635671
pub enum TypeModifier {
636672
Tri,
@@ -665,9 +701,9 @@ impl fmt::Display for Type {
665701
TypeKind::F64 => text.push_str("f64"),
666702
TypeKind::Type => text.push_str("type"),
667703
TypeKind::String => text.push_str("string"),
668-
TypeKind::UserDefined(paths) => {
669-
text.push_str(&format!("{}", paths.first().unwrap()));
670-
for path in &paths[1..] {
704+
TypeKind::UserDefined(x) => {
705+
text.push_str(&format!("{}", x.path.first().unwrap()));
706+
for path in &x.path[1..] {
671707
text.push_str(&format!("::{path}"));
672708
}
673709
}
@@ -801,7 +837,7 @@ impl TryFrom<&syntax_tree::Expression> for Type {
801837
for x in &x.scoped_identifier.scoped_identifier_list {
802838
name.push(x.identifier.identifier_token.token.text);
803839
}
804-
let kind = TypeKind::UserDefined(name);
840+
let kind = TypeKind::UserDefined(UserDefinedType::new(name));
805841
let mut width = Vec::new();
806842
if let Some(ref x) = x.expression_identifier_opt {
807843
let x = &x.width;
@@ -902,7 +938,7 @@ impl From<&syntax_tree::ScalarType> for Type {
902938
for x in &ident.scoped_identifier_list {
903939
name.push(x.identifier.identifier_token.token.text);
904940
}
905-
let kind = TypeKind::UserDefined(name);
941+
let kind = TypeKind::UserDefined(UserDefinedType::new(name));
906942
let mut width = Vec::new();
907943
if let Some(ref x) = x.scalar_type_opt {
908944
let x = &x.width;

crates/analyzer/src/symbol_table.rs

+33-2
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,12 @@ impl SymbolTable {
118118
if let TypeKind::UserDefined(ref x) = kind {
119119
// Detect infinite loop in trace_user_defined
120120
if let Some(last_found) = context.last_found {
121-
if *x.first().unwrap() == last_found.token.text {
121+
if *x.path.first().unwrap() == last_found.token.text {
122122
return Ok(context);
123123
}
124124
}
125125

126-
let symbol = self.resolve(&SymbolPath::new(x), &context.namespace)?;
126+
let symbol = self.resolve(&SymbolPath::new(&x.path), &context.namespace)?;
127127
match symbol.found.kind {
128128
SymbolKind::SystemVerilog => context.sv_member = true,
129129
SymbolKind::TypeDef(x) => {
@@ -447,6 +447,32 @@ impl SymbolTable {
447447
}
448448
}
449449

450+
pub fn get_user_defined(&self) -> Vec<(SymbolId, SymbolId)> {
451+
let mut resolved = Vec::new();
452+
for symbol in self.symbol_table.values() {
453+
if let Some(x) = symbol.kind.get_type() {
454+
if let TypeKind::UserDefined(x) = &x.kind {
455+
let path = SymbolPath::new(&x.path);
456+
if let Ok(type_symbol) = self.resolve(&path, &symbol.namespace) {
457+
resolved.push((symbol.id, type_symbol.found.id));
458+
}
459+
}
460+
}
461+
}
462+
resolved
463+
}
464+
465+
pub fn set_user_defined(&mut self, resolved: Vec<(SymbolId, SymbolId)>) {
466+
for (id, type_id) in resolved {
467+
let symbol = self.symbol_table.get_mut(&id).unwrap();
468+
if let Some(x) = symbol.kind.get_type_mut() {
469+
if let TypeKind::UserDefined(x) = &mut x.kind {
470+
x.symbol = Some(type_id);
471+
}
472+
}
473+
}
474+
}
475+
450476
pub fn add_project_local(&mut self, prj: StrId, from: StrId, to: StrId) {
451477
self.project_local_table
452478
.entry(prj)
@@ -1073,6 +1099,11 @@ pub fn apply_import() {
10731099
SYMBOL_TABLE.with(|f| f.borrow_mut().apply_import())
10741100
}
10751101

1102+
pub fn resolve_user_defined() {
1103+
let resolved = SYMBOL_TABLE.with(|f| f.borrow().get_user_defined());
1104+
SYMBOL_TABLE.with(|f| f.borrow_mut().set_user_defined(resolved))
1105+
}
1106+
10761107
pub fn add_project_local(prj: StrId, from: StrId, to: StrId) {
10771108
SYMBOL_TABLE.with(|f| f.borrow_mut().add_project_local(prj, from, to))
10781109
}

crates/languageserver/src/server.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -912,16 +912,18 @@ fn completion_member(url: &Url, line: usize, column: usize, text: &str) -> Vec<C
912912
VerylSymbolKind::Port(x) => {
913913
if let Some(ref x) = x.r#type {
914914
if let TypeKind::UserDefined(ref x) = x.kind {
915-
if let Ok(symbol) = symbol_table::resolve((x, &namespace)) {
916-
items.append(&mut get_member(&symbol.found));
915+
if let Some(id) = x.symbol {
916+
let symbol = symbol_table::get(id).unwrap();
917+
items.append(&mut get_member(&symbol));
917918
}
918919
}
919920
}
920921
}
921922
VerylSymbolKind::Variable(x) => {
922923
if let TypeKind::UserDefined(ref x) = x.r#type.kind {
923-
if let Ok(symbol) = symbol_table::resolve((x, &namespace)) {
924-
items.append(&mut get_member(&symbol.found));
924+
if let Some(id) = x.symbol {
925+
let symbol = symbol_table::get(id).unwrap();
926+
items.append(&mut get_member(&symbol));
925927
}
926928
}
927929
}

0 commit comments

Comments
 (0)