Change origin of define to optional

This commit is contained in:
dalance 2019-11-12 19:05:38 +09:00
parent 62cdd6c277
commit e20d42b1db
2 changed files with 61 additions and 26 deletions

View File

@ -1,6 +1,9 @@
# Change Log # Change Log
## [Unreleased](https://github.com/dalance/sv-parser/compare/v0.3.7...Unreleased) - ReleaseDate ## [Unreleased](https://github.com/dalance/sv-parser/compare/v0.3.7...Unreleased) - ReleaseDate
* [Changed] origin of define to optional
## [v0.3.7](https://github.com/dalance/sv-parser/compare/v0.3.6...v0.3.7) - 2019-11-06 ## [v0.3.7](https://github.com/dalance/sv-parser/compare/v0.3.6...v0.3.7) - 2019-11-06
* [Fixed] apply workaround for static class method call * [Fixed] apply workaround for static class method call

View File

@ -22,8 +22,7 @@ pub struct PreprocessedText {
#[derive(Debug)] #[derive(Debug)]
pub struct Origin { pub struct Origin {
range: Range, range: Range,
origin_path: PathBuf, origin: Option<(PathBuf, Range)>,
origin_range: Range,
} }
impl PreprocessedText { impl PreprocessedText {
@ -34,16 +33,19 @@ impl PreprocessedText {
} }
} }
fn push<T: AsRef<Path>>(&mut self, s: &str, origin_path: T, origin_range: Range) { fn push<T: AsRef<Path>>(&mut self, s: &str, origin: Option<(T, Range)>) {
let base = self.text.len(); let base = self.text.len();
self.text.push_str(s); self.text.push_str(s);
let range = Range::new(base, base + s.len()); let origin = if let Some((origin_path, origin_range)) = origin {
let origin = Origin { let origin_path = PathBuf::from(origin_path.as_ref());
range, Some((origin_path, origin_range))
origin_path: PathBuf::from(origin_path.as_ref()), } else {
origin_range, None
}; };
let range = Range::new(base, base + s.len());
let origin = Origin { range, origin };
self.origins.insert(range, origin); self.origins.insert(range, origin);
} }
@ -64,8 +66,12 @@ impl PreprocessedText {
pub fn origin(&self, pos: usize) -> Option<(&PathBuf, usize)> { pub fn origin(&self, pos: usize) -> Option<(&PathBuf, usize)> {
let origin = self.origins.get(&Range::new(pos, pos + 1)); let origin = self.origins.get(&Range::new(pos, pos + 1));
if let Some(origin) = origin { if let Some(origin) = origin {
let ret_pos = pos - origin.range.begin + origin.origin_range.begin; if let Some((ref origin_path, ref origin_range)) = origin.origin {
Some((&origin.origin_path, ret_pos)) let ret_pos = pos - origin.range.begin + origin_range.begin;
Some((&origin_path, ret_pos))
} else {
None
}
} else { } else {
None None
} }
@ -76,8 +82,33 @@ impl PreprocessedText {
pub struct Define { pub struct Define {
identifier: String, identifier: String,
arguments: Vec<(String, Option<String>)>, arguments: Vec<(String, Option<String>)>,
text: Option<(String, Range)>, text: Option<DefineText>,
path: PathBuf, }
#[derive(Clone, Debug)]
pub struct DefineText {
text: String,
origin: Option<(PathBuf, Range)>,
}
impl Define {
pub fn new(
ident: String,
args: Vec<(String, Option<String>)>,
text: Option<DefineText>,
) -> Self {
Define {
identifier: ident,
arguments: args,
text,
}
}
}
impl DefineText {
pub fn new(text: String, origin: Option<(PathBuf, Range)>) -> Self {
DefineText { text, origin }
}
} }
pub type Defines = HashMap<String, Option<Define>>; pub type Defines = HashMap<String, Option<Define>>;
@ -159,24 +190,24 @@ fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>>(
NodeEvent::Enter(RefNode::SourceDescriptionNotDirective(x)) if !skip => { NodeEvent::Enter(RefNode::SourceDescriptionNotDirective(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), 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 => 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), 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)) 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), 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)) 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), 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)) if !skip => {
let (_, _, ref ifid, ref ifbody, ref elsif, ref elsebody, _, _) = x.nodes; let (_, _, ref ifid, ref ifbody, ref elsif, ref elsebody, _, _) = x.nodes;
@ -266,7 +297,10 @@ fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>>(
let text: Locate = text.try_into().unwrap(); let text: Locate = text.try_into().unwrap();
let range = Range::new(text.offset, text.offset + text.len); let range = Range::new(text.offset, text.offset + text.len);
let text = String::from(text.str(&s)); let text = String::from(text.str(&s));
Some((text, range)) Some(DefineText {
text,
origin: Some((PathBuf::from(path.as_ref()), range)),
})
} else { } else {
None None
}; };
@ -275,7 +309,6 @@ fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>>(
identifier: id.clone(), identifier: id.clone(),
arguments: define_args, arguments: define_args,
text: define_text, text: define_text,
path: PathBuf::from(path.as_ref()),
}; };
defines.insert(id, Some(define)); defines.insert(id, Some(define));
@ -297,7 +330,7 @@ fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>>(
IncludeCompilerDirective::TextMacroUsage(x) => { IncludeCompilerDirective::TextMacroUsage(x) => {
let (_, _, ref x) = x.nodes; let (_, _, ref x) = x.nodes;
skip_nodes.push(x.into()); skip_nodes.push(x.into());
if let Some((p, _, _, _)) = if let Some((p, _, _)) =
resolve_text_macro_usage(x, s, path.as_ref(), &defines, include_paths)? resolve_text_macro_usage(x, s, path.as_ref(), &defines, include_paths)?
{ {
let p = p.trim().trim_matches('"'); let p = p.trim().trim_matches('"');
@ -324,10 +357,10 @@ fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>>(
ret.merge(include); ret.merge(include);
} }
NodeEvent::Enter(RefNode::TextMacroUsage(x)) if !skip => { NodeEvent::Enter(RefNode::TextMacroUsage(x)) if !skip => {
if let Some((text, path, range, new_defines)) = if let Some((text, origin, new_defines)) =
resolve_text_macro_usage(x, s, path.as_ref(), &defines, include_paths)? resolve_text_macro_usage(x, s, path.as_ref(), &defines, include_paths)?
{ {
ret.push(&text, path, range); ret.push(&text, origin);
defines = new_defines; defines = new_defines;
} }
} }
@ -402,7 +435,7 @@ fn resolve_text_macro_usage<T: AsRef<Path>, U: AsRef<Path>>(
path: T, path: T,
defines: &Defines, defines: &Defines,
include_paths: &[U], include_paths: &[U],
) -> Result<Option<(String, PathBuf, Range, Defines)>, Error> { ) -> Result<Option<(String, Option<(PathBuf, Range)>, Defines)>, Error> {
let (_, ref name, ref args) = x.nodes; let (_, ref name, ref args) = x.nodes;
let id = identifier((&name.nodes.0).into(), &s).unwrap(); let id = identifier((&name.nodes.0).into(), &s).unwrap();
@ -451,9 +484,9 @@ fn resolve_text_macro_usage<T: AsRef<Path>, U: AsRef<Path>>(
arg_map.insert(String::from(arg), value); arg_map.insert(String::from(arg), value);
} }
if let Some((ref text, ref range)) = define.text { if let Some(ref text) = define.text {
let mut replaced = String::from(""); let mut replaced = String::from("");
for text in split_text(&text) { for text in split_text(&text.text) {
if let Some(value) = arg_map.get(&text) { if let Some(value) = arg_map.get(&text) {
replaced.push_str(*value); replaced.push_str(*value);
} else { } else {
@ -475,8 +508,7 @@ fn resolve_text_macro_usage<T: AsRef<Path>, U: AsRef<Path>>(
preprocess_str(&replaced, path.as_ref(), &defines, include_paths)?; preprocess_str(&replaced, path.as_ref(), &defines, include_paths)?;
Ok(Some(( Ok(Some((
String::from(replaced.text()), String::from(replaced.text()),
define.path.clone(), text.origin.clone(),
*range,
new_defines, new_defines,
))) )))
} else { } else {