mirror of
https://github.com/SpaceManiac/SpacemanDMM.git
synced 2025-12-23 05:36:47 +00:00
Use the reference as the location of builtins
This commit is contained in:
parent
ec7087ebb8
commit
4aa6a998bb
3 changed files with 39 additions and 17 deletions
|
|
@ -2,20 +2,26 @@
|
|||
|
||||
use super::objtree::*;
|
||||
use super::ast::*;
|
||||
use super::{Location, DMError};
|
||||
use super::{Location, FileId, DMError};
|
||||
|
||||
/// Register BYOND builtins into the specified object tree.
|
||||
pub fn register_builtins(tree: &mut ObjectTree) -> Result<(), DMError> {
|
||||
let location = Location {
|
||||
file: FileId::builtins(),
|
||||
line: 1,
|
||||
column: 1,
|
||||
};
|
||||
|
||||
macro_rules! entries {
|
||||
($($($elem:ident)/ * $(= $val:expr)*;)*) => {
|
||||
$(loop {
|
||||
#![allow(unreachable_code)]
|
||||
let elems = [$(stringify!($elem)),*];
|
||||
$(
|
||||
tree.add_var(Location::default(), elems.iter().cloned(), $val)?;
|
||||
tree.add_var(location, elems.iter().cloned(), $val)?;
|
||||
break;
|
||||
)*
|
||||
tree.add_entry(Location::default(), elems.iter().cloned())?;
|
||||
tree.add_entry(location, elems.iter().cloned())?;
|
||||
break;
|
||||
})*
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,19 @@ use std::cell::{RefCell, Ref};
|
|||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub struct FileId(u32);
|
||||
|
||||
const BAD_FILE_ID: FileId = FileId(::std::u32::MAX);
|
||||
const FILEID_BAD: FileId = FileId(::std::u32::MAX);
|
||||
const FILEID_BUILTINS: FileId = FileId(0xfffffffe);
|
||||
|
||||
impl Default for FileId {
|
||||
fn default() -> FileId {
|
||||
BAD_FILE_ID
|
||||
FILEID_BAD
|
||||
}
|
||||
}
|
||||
|
||||
impl FileId {
|
||||
#[inline]
|
||||
pub fn builtins() -> FileId {
|
||||
FILEID_BUILTINS
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -38,9 +46,12 @@ impl Context {
|
|||
|
||||
/// Look up a file path by its index returned from `register_file`.
|
||||
pub fn file_path(&self, file: FileId) -> PathBuf {
|
||||
if file == FILEID_BUILTINS {
|
||||
return "(builtins)".into();
|
||||
}
|
||||
let files = self.files.borrow();
|
||||
let idx = file.0 as usize;
|
||||
if idx > files.len() { // includes BAD_FILE_ID
|
||||
if idx > files.len() {
|
||||
"(unknown)".into()
|
||||
} else {
|
||||
files[idx].to_owned()
|
||||
|
|
|
|||
|
|
@ -133,13 +133,18 @@ impl<'a, R: io::RequestRead, W: io::ResponseWrite> Engine<'a, R, W> {
|
|||
path_to_url(self.root.join(self.context.file_path(file)))
|
||||
}
|
||||
|
||||
fn convert_location(&self, loc: dm::Location) -> Result<langserver::Location, jsonrpc::Error> {
|
||||
fn convert_location(&self, loc: dm::Location, one: &str, two: &str, three: &str) -> 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)?,
|
||||
uri: if loc.file == dm::FileId::builtins() {
|
||||
Url::parse(&format!("https://secure.byond.com/docs/ref/info.html#{}{}{}", one, two, three))
|
||||
.map_err(invalid_request)?
|
||||
} else {
|
||||
self.file_url(loc.file)?
|
||||
},
|
||||
range: langserver::Range::new(pos, pos),
|
||||
})
|
||||
}
|
||||
|
|
@ -299,7 +304,7 @@ impl<'a, R: io::RequestRead, W: io::ResponseWrite> Engine<'a, R, W> {
|
|||
results.push(SymbolInformation {
|
||||
name: name.to_owned(),
|
||||
kind: SymbolKind::Constant,
|
||||
location: self.convert_location(location)?,
|
||||
location: self.convert_location(location, "/DM", "/preprocessor/", name)?,
|
||||
container_name: None,
|
||||
});
|
||||
}
|
||||
|
|
@ -310,8 +315,8 @@ impl<'a, R: io::RequestRead, W: io::ResponseWrite> Engine<'a, R, W> {
|
|||
results.push(SymbolInformation {
|
||||
name: ty.name.clone(),
|
||||
kind: SymbolKind::Class,
|
||||
location: self.convert_location(ty.location)?,
|
||||
container_name: Some(ty.path.clone()),
|
||||
location: self.convert_location(ty.location, &ty.path, "", "")?,
|
||||
container_name: Some(ty.path[..ty.path.len() - ty.name.len() - 1].to_owned()),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -324,7 +329,7 @@ impl<'a, R: io::RequestRead, W: io::ResponseWrite> Engine<'a, R, W> {
|
|||
results.push(SymbolInformation {
|
||||
name: var_name.clone(),
|
||||
kind: SymbolKind::Field,
|
||||
location: self.convert_location(decl.location)?,
|
||||
location: self.convert_location(decl.location, &ty.path, "/var/", var_name)?,
|
||||
container_name: Some(ty.path.clone()),
|
||||
});
|
||||
}
|
||||
|
|
@ -343,7 +348,7 @@ impl<'a, R: io::RequestRead, W: io::ResponseWrite> Engine<'a, R, W> {
|
|||
} else {
|
||||
SymbolKind::Method
|
||||
},
|
||||
location: self.convert_location(decl.location)?,
|
||||
location: self.convert_location(decl.location, &ty.path, "/proc/", proc_name)?,
|
||||
container_name: Some(ty.path.clone()),
|
||||
});
|
||||
}
|
||||
|
|
@ -352,10 +357,10 @@ impl<'a, R: io::RequestRead, W: io::ResponseWrite> Engine<'a, R, W> {
|
|||
}
|
||||
let elapsed = start.elapsed();
|
||||
eprintln!(" {} results in {}.{:03}s", results.len(), elapsed.as_secs(), elapsed.subsec_nanos() / 1_000_000);
|
||||
// TODO: break if the query is too general, e.g. `obj/` on
|
||||
// tgstation has 9100+ results. Search is very fast but
|
||||
// serialization is very slow (30+ seconds).
|
||||
results.truncate(200);
|
||||
#[cfg(debug_assertions)] {
|
||||
// Serializing all these to the debug log is very slow.
|
||||
results.truncate(100);
|
||||
}
|
||||
Some(results)
|
||||
} else {
|
||||
None
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue