Skip to content

Commit e4a9e4a

Browse files
authored
refactor(extras): build the editor services on the syntax tree (#94)
1 parent bc28c06 commit e4a9e4a

39 files changed

Lines changed: 2204 additions & 2618 deletions

Cargo.lock

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extra/mpl-language-server-wasm/src/lib.rs

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,42 @@
44
//! `JsValue` arguments into pure Rust types, calls the corresponding
55
//! `mpl_language_server::*` function, and re-encodes the result.
66
7-
use mpl_lang::{Query, compile, query::Source};
7+
use mpl_lang::{CompileError, Query, compile2, query::Source};
88
use mpl_language_server::SystemParamSpec;
99
use serde::Serialize;
1010
use wasm_bindgen::prelude::*;
1111

1212
mod system_params;
1313

1414
/// Parse `query` (ignoring warnings) into a `Query` AST. Used by the
15-
/// `parse_*` / `extract_dataset` shims below. Errors are stringified via
16-
/// `Debug` to avoid pulling miette's fancy formatter into the wasm bundle.
15+
/// `parse_*` / `extract_dataset` shims below.
1716
fn parse_with_system_param_specs(
1817
query: &str,
1918
system_params: &[SystemParamSpec],
2019
) -> Result<Query, String> {
2120
let params = mpl_language_server::to_compile_params(system_params);
22-
compile(query, params)
21+
compile2(query, params)
2322
.map(|(q, _warnings)| q)
24-
.map_err(|e| format!("{e:?}"))
23+
.map_err(|e| describe(&e))
24+
}
25+
26+
/// What went wrong, as a line the host can show.
27+
///
28+
/// Each variant is rendered through the error it carries. Naming them one by one
29+
/// keeps miette's formatter and the grammar's rule names out of the wasm bundle,
30+
/// which is worth more here than the shorter spelling.
31+
fn describe(e: &CompileError) -> String {
32+
match e {
33+
CompileError::ParserV2(errors) => errors
34+
.iter()
35+
.map(ToString::to_string)
36+
.collect::<Vec<_>>()
37+
.join("; "),
38+
CompileError::Type(e) => e.to_string(),
39+
CompileError::Group(e) => e.to_string(),
40+
CompileError::Ifdef(e) => e.to_string(),
41+
CompileError::Parse(_) => "parse error".to_string(),
42+
}
2543
}
2644

2745
/// Pure rust JSON parse helper.
@@ -86,13 +104,59 @@ pub fn diagnostics(query: &str, system_params: JsValue) -> JsValue {
86104
}
87105

88106
/// Tokenises `query` for syntax highlighting.
107+
///
108+
/// Always returns an array: a query that does not parse yields the tokens it
109+
/// does have, so the editor keeps its colours while the user is still typing.
89110
#[must_use]
90111
#[wasm_bindgen]
91112
pub fn tokenize(query: &str) -> JsValue {
92113
let tokens = mpl_language_server::collect_tokens(query);
93114
to_js_value(&tokens)
94115
}
95116

117+
/// Returns the token at byte `offset` as `{ from, to, type }`, or `null` where
118+
/// there is nothing to report (whitespace, punctuation, past the end).
119+
///
120+
/// A `::`-qualified function name comes back whole, so hovering either segment
121+
/// of `prom::rate` yields the name the stdlib is keyed by. Callers read the text
122+
/// out of their own copy with the returned span.
123+
#[must_use]
124+
#[wasm_bindgen]
125+
pub fn token_at(query: &str, offset: usize) -> JsValue {
126+
to_js_value(&mpl_language_server::token_at(query, offset))
127+
}
128+
129+
/// Looks up an MPL keyword by name and returns its description and syntax, or
130+
/// `null` when the word names no keyword.
131+
#[must_use]
132+
#[wasm_bindgen]
133+
pub fn keyword_info(label: &str) -> JsValue {
134+
to_js_value(&mpl_language_server::keyword_info(label))
135+
}
136+
137+
/// Whether `name` has to be backtick-escaped to be read as an identifier.
138+
#[must_use]
139+
#[wasm_bindgen]
140+
pub fn needs_escape(name: &str) -> bool {
141+
mpl_language_server::needs_escape(name)
142+
}
143+
144+
/// `name` written so it reads as an identifier, adding backticks only where
145+
/// they are required.
146+
#[must_use]
147+
#[wasm_bindgen]
148+
pub fn escape_ident(name: &str) -> String {
149+
mpl_language_server::escape_ident(name)
150+
}
151+
152+
/// The text a completion inserts for `name`. Set `in_backtick` when the opening
153+
/// backtick is already in the document and the replacement starts after it.
154+
#[must_use]
155+
#[wasm_bindgen]
156+
pub fn apply_text_for_ident(name: &str, in_backtick: bool) -> String {
157+
mpl_language_server::apply_text_for_ident(name, in_backtick)
158+
}
159+
96160
/// Extracts the dataset name from an `MPL` query string.
97161
///
98162
/// For `Simple` queries, returns the dataset from the source.

extra/mpl-language-server/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ rust-version = "1.92.0"
1414
mpl-lang = { path = "../..", default-features = false }
1515
serde = { version = "1", features = ["derive"] }
1616
serde_json = "1"
17-
pest = "2.8.6"
17+
rowan = "0.16"
1818
strsim = "0.11.1"
1919
miette = { version = "7.6.0", features = ["serde"] }
2020

0 commit comments

Comments
 (0)