Fix empty ifdef issue #10

This commit is contained in:
dalance 2020-08-28 19:51:04 +09:00
parent 9727db03eb
commit 9c935af397
3 changed files with 86 additions and 19 deletions

View File

@ -2,6 +2,8 @@
## [Unreleased](https://github.com/dalance/sv-parser/compare/v0.8.1...Unreleased) - ReleaseDate ## [Unreleased](https://github.com/dalance/sv-parser/compare/v0.8.1...Unreleased) - ReleaseDate
* [Fixed] empty ifdef issue [#10](https://github.com/dalance/sv-parser/issues/10)
## [v0.8.1](https://github.com/dalance/sv-parser/compare/v0.8.0...v0.8.1) - 2020-08-28 ## [v0.8.1](https://github.com/dalance/sv-parser/compare/v0.8.0...v0.8.1) - 2020-08-28
* [Fixed] text macro with single line comment [#12](https://github.com/dalance/sv-parser/issues/12) * [Fixed] text macro with single line comment [#12](https://github.com/dalance/sv-parser/issues/12)

View File

@ -142,6 +142,34 @@ pub fn preprocess<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
) )
} }
struct SkipNodes<'a> {
nodes: Vec<RefNode<'a>>,
}
impl<'a> SkipNodes<'a> {
fn new() -> Self {
Self { nodes: vec![] }
}
fn push(&mut self, node: RefNode<'a>) {
// if a node doesn't have locate, the node should be ignored
// because the node can be identified in tree.
let mut have_locate = false;
for x in node.clone() {
if let RefNode::Locate(_) = x {
have_locate = true;
}
}
if have_locate {
self.nodes.push(node);
}
}
fn contains(&self, node: &RefNode<'a>) -> bool {
self.nodes.contains(node)
}
}
pub fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>( pub fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
s: &str, s: &str,
path: T, path: T,
@ -152,7 +180,7 @@ pub fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
resolve_depth: usize, resolve_depth: usize,
) -> Result<(PreprocessedText, Defines), Error> { ) -> Result<(PreprocessedText, Defines), Error> {
let mut skip = false; let mut skip = false;
let mut skip_nodes = vec![]; let mut skip_nodes = SkipNodes::new();
let mut defines = HashMap::new(); let mut defines = HashMap::new();
let mut last_item_line = None; let mut last_item_line = None;
@ -196,6 +224,10 @@ pub fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
} }
} }
} }
if skip {
continue;
}
match n.clone() { match n.clone() {
NodeEvent::Enter(RefNode::SourceDescriptionNotDirective(x)) => { NodeEvent::Enter(RefNode::SourceDescriptionNotDirective(x)) => {
let locate: Locate = x.try_into().unwrap(); let locate: Locate = x.try_into().unwrap();
@ -224,12 +256,12 @@ pub fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
_ => (), _ => (),
} }
match n { match n {
NodeEvent::Enter(RefNode::ResetallCompilerDirective(x)) if !skip => { NodeEvent::Enter(RefNode::ResetallCompilerDirective(x)) => {
let locate: Locate = x.try_into().unwrap(); let locate: Locate = x.try_into().unwrap();
let range = Range::new(locate.offset, locate.offset + locate.len); let range = Range::new(locate.offset, locate.offset + locate.len);
ret.push(locate.str(&s), Some((path.as_ref(), range))); ret.push(locate.str(&s), Some((path.as_ref(), range)));
} }
NodeEvent::Enter(RefNode::UndefineCompilerDirective(x)) if !skip => { NodeEvent::Enter(RefNode::UndefineCompilerDirective(x)) => {
skip_nodes.push(x.into()); skip_nodes.push(x.into());
skip = true; skip = true;
@ -237,42 +269,40 @@ pub fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
let id = identifier((&name.nodes.0).into(), &s).unwrap(); let id = identifier((&name.nodes.0).into(), &s).unwrap();
defines.remove(&id); defines.remove(&id);
} }
NodeEvent::Enter(RefNode::UndefineallCompilerDirective(x)) if !skip => { NodeEvent::Enter(RefNode::UndefineallCompilerDirective(x)) => {
skip_nodes.push(x.into()); skip_nodes.push(x.into());
skip = true; skip = true;
defines.clear(); defines.clear();
} }
NodeEvent::Enter(RefNode::SourceDescriptionNotDirective(x)) if !skip => { NodeEvent::Enter(RefNode::SourceDescriptionNotDirective(x)) => {
let locate: Locate = x.try_into().unwrap(); let locate: Locate = x.try_into().unwrap();
let range = Range::new(locate.offset, locate.offset + locate.len); let range = Range::new(locate.offset, locate.offset + locate.len);
ret.push(locate.str(&s), Some((path.as_ref(), range))); ret.push(locate.str(&s), Some((path.as_ref(), range)));
} }
NodeEvent::Enter(RefNode::SourceDescription(SourceDescription::StringLiteral(x))) NodeEvent::Enter(RefNode::SourceDescription(SourceDescription::StringLiteral(x))) => {
if !skip =>
{
let locate: Locate = (&**x).try_into().unwrap(); let locate: Locate = (&**x).try_into().unwrap();
let range = Range::new(locate.offset, locate.offset + locate.len); let range = Range::new(locate.offset, locate.offset + locate.len);
ret.push(locate.str(&s), Some((path.as_ref(), range))); ret.push(locate.str(&s), Some((path.as_ref(), range)));
} }
NodeEvent::Enter(RefNode::SourceDescription(SourceDescription::EscapedIdentifier( NodeEvent::Enter(RefNode::SourceDescription(SourceDescription::EscapedIdentifier(
x, x,
))) if !skip => { ))) => {
let locate: Locate = (&**x).try_into().unwrap(); let locate: Locate = (&**x).try_into().unwrap();
let range = Range::new(locate.offset, locate.offset + locate.len); let range = Range::new(locate.offset, locate.offset + locate.len);
ret.push(locate.str(&s), Some((path.as_ref(), range))); ret.push(locate.str(&s), Some((path.as_ref(), range)));
} }
NodeEvent::Enter(RefNode::KeywordsDirective(x)) if !skip => { NodeEvent::Enter(RefNode::KeywordsDirective(x)) => {
let locate: Locate = x.try_into().unwrap(); let locate: Locate = x.try_into().unwrap();
let range = Range::new(locate.offset, locate.offset + locate.len); let range = Range::new(locate.offset, locate.offset + locate.len);
ret.push(locate.str(&s), Some((path.as_ref(), range))); ret.push(locate.str(&s), Some((path.as_ref(), range)));
} }
NodeEvent::Enter(RefNode::EndkeywordsDirective(x)) if !skip => { NodeEvent::Enter(RefNode::EndkeywordsDirective(x)) => {
let locate: Locate = x.try_into().unwrap(); let locate: Locate = x.try_into().unwrap();
let range = Range::new(locate.offset, locate.offset + locate.len); let range = Range::new(locate.offset, locate.offset + locate.len);
ret.push(locate.str(&s), Some((path.as_ref(), range))); ret.push(locate.str(&s), Some((path.as_ref(), range)));
} }
NodeEvent::Enter(RefNode::IfdefDirective(x)) if !skip => { NodeEvent::Enter(RefNode::IfdefDirective(x)) => {
let (_, ref keyword, ref ifid, ref ifbody, ref elsif, ref elsebody, _, _) = x.nodes; let (_, ref keyword, ref ifid, ref ifbody, ref elsif, ref elsebody, _, _) = x.nodes;
skip_nodes.push(keyword.into()); skip_nodes.push(keyword.into());
skip_nodes.push(ifid.into()); skip_nodes.push(ifid.into());
@ -308,19 +338,19 @@ pub fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
} }
} }
} }
NodeEvent::Enter(RefNode::WhiteSpace(x)) if !skip && !strip_comments => { NodeEvent::Enter(RefNode::WhiteSpace(x)) if !strip_comments => {
if let WhiteSpace::Space(_) = x { if let WhiteSpace::Space(_) = x {
let locate: Locate = x.try_into().unwrap(); let locate: Locate = x.try_into().unwrap();
let range = Range::new(locate.offset + locate.len, locate.offset + locate.len); let range = Range::new(locate.offset + locate.len, locate.offset + locate.len);
ret.push(locate.str(&s), Some((path.as_ref(), range))); ret.push(locate.str(&s), Some((path.as_ref(), range)));
} }
} }
NodeEvent::Enter(RefNode::Comment(x)) if !skip && !strip_comments => { NodeEvent::Enter(RefNode::Comment(x)) if !strip_comments => {
let locate: Locate = x.try_into().unwrap(); let locate: Locate = x.try_into().unwrap();
let range = Range::new(locate.offset, locate.offset + locate.len); let range = Range::new(locate.offset, locate.offset + locate.len);
ret.push(locate.str(&s), Some((path.as_ref(), range))); ret.push(locate.str(&s), Some((path.as_ref(), range)));
} }
NodeEvent::Enter(RefNode::IfndefDirective(x)) if !skip => { NodeEvent::Enter(RefNode::IfndefDirective(x)) => {
let (_, ref keyword, ref ifid, ref ifbody, ref elsif, ref elsebody, _, _) = x.nodes; let (_, ref keyword, ref ifid, ref ifbody, ref elsif, ref elsebody, _, _) = x.nodes;
skip_nodes.push(keyword.into()); skip_nodes.push(keyword.into());
skip_nodes.push(ifid.into()); skip_nodes.push(ifid.into());
@ -356,7 +386,7 @@ pub fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
} }
} }
} }
NodeEvent::Enter(RefNode::TextMacroDefinition(x)) if !skip => { NodeEvent::Enter(RefNode::TextMacroDefinition(x)) => {
skip_nodes.push(x.into()); skip_nodes.push(x.into());
skip = true; skip = true;
@ -405,7 +435,7 @@ pub fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
defines.insert(id, Some(define)); defines.insert(id, Some(define));
} }
NodeEvent::Enter(RefNode::IncludeCompilerDirective(x)) if !skip && !ignore_include => { NodeEvent::Enter(RefNode::IncludeCompilerDirective(x)) if !ignore_include => {
skip_nodes.push(x.into()); skip_nodes.push(x.into());
skip = true; skip = true;
@ -474,7 +504,7 @@ pub fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
defines = new_defines; defines = new_defines;
ret.merge(include); ret.merge(include);
} }
NodeEvent::Enter(RefNode::TextMacroUsage(x)) if !skip => { NodeEvent::Enter(RefNode::TextMacroUsage(x)) => {
skip_nodes.push(x.into()); skip_nodes.push(x.into());
skip = true; skip = true;
@ -491,7 +521,7 @@ pub fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
defines = new_defines; defines = new_defines;
} }
} }
NodeEvent::Enter(RefNode::PositionCompilerDirective(x)) if !skip => { NodeEvent::Enter(RefNode::PositionCompilerDirective(x)) => {
skip_nodes.push(x.into()); skip_nodes.push(x.into());
skip = true; skip = true;
@ -1018,6 +1048,27 @@ endmodule
r##" r##"
interface foo #(WIDTH = 42 ) (); interface foo #(WIDTH = 42 ) ();
endinterface endinterface
"##
);
}
#[test]
fn test14() {
let (ret, _) = preprocess(
get_testcase("test14.sv"),
&HashMap::new(),
&[] as &[String],
false,
false,
)
.unwrap();
assert_eq!(
ret.text(),
r##"module A;
wire a = 1'b0;
endmodule
"## "##
); );
} }

View File

@ -0,0 +1,14 @@
module A;
`ifdef OPT_1
//wire a = 1'b1;
`else
wire a = 1'b0;
`endif
`ifdef DEBUG
`ifdef OPT_2
//wire b = 1'b1;
`else
wire b = 1'b0;
`endif
`endif
endmodule