From 912cc7730fb56e4f092dfd4ad04a95361fc6b85a Mon Sep 17 00:00:00 2001 From: Tad Hardesty Date: Mon, 12 Mar 2018 21:50:48 -0700 Subject: [PATCH] Add defines to symbol lookup, with location info --- src/dreammaker/error.rs | 12 ++++++++++++ src/dreammaker/preprocessor.rs | 7 ++++--- src/langserver/main.rs | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/dreammaker/error.rs b/src/dreammaker/error.rs index 7ea21d43..931f71e2 100644 --- a/src/dreammaker/error.rs +++ b/src/dreammaker/error.rs @@ -23,6 +23,8 @@ pub struct Context { files: RefCell>, /// A list of errors, warnings, and other diagnostics generated. errors: RefCell>, + /// A list of all preprocessor symbols in the project. + defines: RefCell>, } 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(&self, w: &mut W, error: &DMError) -> io::Result<()> { writeln!(w, "{}, line {}, column {}:", diff --git a/src/dreammaker/preprocessor.rs b/src/dreammaker/preprocessor.rs index 6dfbab9d..f2d3d70b 100644 --- a/src/dreammaker/preprocessor.rs +++ b/src/dreammaker/preprocessor.rs @@ -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 { 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 { diff --git a/src/langserver/main.rs b/src/langserver/main.rs index 1ef58d83..a81baba5 100644 --- a/src/langserver/main.rs +++ b/src/langserver/main.rs @@ -100,6 +100,21 @@ impl<'a, R: io::RequestRead, W: io::ResponseWrite> Engine<'a, R, W> { ) } + fn file_url(&self, file: dm::FileId) -> Result { + path_to_url(self.root.join(self.context.file_path(file))) + } + + fn convert_location(&self, loc: dm::Location) -> Result { + 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)