Add defines to symbol lookup, with location info

This commit is contained in:
Tad Hardesty 2018-03-12 21:50:48 -07:00
parent 20a985b450
commit 912cc7730f
3 changed files with 48 additions and 4 deletions

View file

@ -23,6 +23,8 @@ pub struct Context {
files: RefCell<Vec<PathBuf>>,
/// A list of errors, warnings, and other diagnostics generated.
errors: RefCell<Vec<DMError>>,
/// A list of all preprocessor symbols in the project.
defines: RefCell<Vec<(String, Location)>>,
}
impl Context {
@ -55,6 +57,16 @@ impl Context {
Ref::map(self.errors.borrow(), |x| &**x)
}
/// Push a preprocessor symbol to the symbol list.
pub fn register_define(&self, name: String, location: Location) {
self.defines.borrow_mut().push((name, location));
}
/// Access the list of preprocessor symbols.
pub fn defines(&self) -> Ref<[(String, Location)]> {
Ref::map(self.defines.borrow(), |x| &**x)
}
/// Pretty-print a `DMError` to the given output.
pub fn pretty_print_error<W: io::Write>(&self, w: &mut W, error: &DMError) -> io::Result<()> {
writeln!(w, "{}, line {}, column {}:",

View file

@ -252,17 +252,17 @@ impl<'ctx> HasLocation for Preprocessor<'ctx> {
impl<'ctx> Preprocessor<'ctx> {
pub fn new(context: &'ctx Context, env_file: PathBuf) -> io::Result<Self> {
let mut pp = Preprocessor {
context,
env_file: env_file.clone(),
include_stack: IncludeStack {
stack: vec![Include::new(context, env_file.clone())?],
stack: vec![Include::new(context, env_file)?],
},
env_file: env_file,
defines: Default::default(),
maps: Default::default(),
skins: Default::default(),
ifdef_stack: Default::default(),
last_input_loc: Default::default(),
output: Default::default(),
context: context,
};
default_defines(&mut pp.defines);
Ok(pp)
@ -430,6 +430,7 @@ impl<'ctx> Preprocessor<'ctx> {
}
}
}
self.context.register_define(define_name.clone(), self.last_input_loc);
if args.is_empty() {
self.defines.insert(define_name, Define::Constant(subst));
} else {

View file

@ -100,6 +100,21 @@ impl<'a, R: io::RequestRead, W: io::ResponseWrite> Engine<'a, R, W> {
)
}
fn file_url(&self, file: dm::FileId) -> Result<Url, jsonrpc::Error> {
path_to_url(self.root.join(self.context.file_path(file)))
}
fn convert_location(&self, loc: dm::Location) -> Result<langserver::Location, jsonrpc::Error> {
let pos = langserver::Position {
line: loc.line.saturating_sub(1) as u64,
character: loc.column.saturating_sub(1) as u64,
};
Ok(langserver::Location {
uri: self.file_url(loc.file)?,
range: langserver::Range::new(pos, pos),
})
}
// ------------------------------------------------------------------------
// Driver
@ -244,12 +259,27 @@ impl<'a, R: io::RequestRead, W: io::ResponseWrite> Engine<'a, R, W> {
}
};
|params: WorkspaceSymbol| {
const MAX_SYMBOLS_PER_TYPE: usize = 15;
let query = params.query;
eprintln!("{:?}", query);
let mut results = Vec::new();
if query.is_empty() {
None
} else {
let mut results = Vec::new();
let upperquery = query.to_uppercase();
for &(ref name, location) in self.context.defines().iter() {
if name.to_uppercase().contains(&upperquery) {
results.push(SymbolInformation {
name: name.to_owned(),
kind: SymbolKind::Constant,
location: self.convert_location(location)?,
container_name: None,
});
if results.len() >= MAX_SYMBOLS_PER_TYPE { break }
}
}
let slash = query.contains("/");
for (_idx, ty) in self.objtree.graph.node_references() {
if ty.name.starts_with(&query) || (slash && ty.path.contains(&query)) {
@ -265,6 +295,7 @@ impl<'a, R: io::RequestRead, W: io::ResponseWrite> Engine<'a, R, W> {
},
container_name: None,
});
if results.len() >= 2 * MAX_SYMBOLS_PER_TYPE { break }
}
}
Some(results)