Skip to content

Commit

Permalink
- provide exact TextRange for Query::parse() errors.
Browse files Browse the repository at this point in the history
  • Loading branch information
OmarTawfik committed Jan 11, 2025
1 parent f466fe6 commit 2b5df65
Show file tree
Hide file tree
Showing 34 changed files with 210 additions and 274 deletions.
5 changes: 5 additions & 0 deletions .changeset/shiny-feet-shop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nomicfoundation/slang": minor
---

provide exact `TextRange` for `Query::parse()` errors.
10 changes: 0 additions & 10 deletions crates/codegen/runtime/cargo/wasm/src/runtime/config.json.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -170,16 +170,6 @@
"as_getter": true
}
},
"nomic-foundation:slang:parser:parse-error.text-range()": {
"Function": {
"as_getter": true
}
},
"nomic-foundation:slang:parser:parse-error.message()": {
"Function": {
"as_getter": true
}
},
"nomic-foundation:slang:parser:parse-output.tree()": {
"Function": {
"as_getter": true
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -252,12 +252,10 @@ interface cst {

/// Represents an error that occurred while parsing a query.
record query-error {
/// The error message describing what went wrong.
/// A human-readable message describing what went wrong.
message: string,
/// The line number where the error occurred.
line: u32,
/// The column number where the error occurred.
column: u32,
/// The text range where the error occurred in the query code.
text-range: text-range,
}

/// Represents a match found by executing a query.
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ interface parser {
parse: func(kind: nonterminal-kind, input: string) -> parse-output;
}

/// Contains information about where the error occurred and what went wrong.
resource parse-error {
/// Returns the text range where the error occurred in the source code.
text-range: func() -> text-range;
/// Represents an error that occurred while parsing source code.
record parse-error {
/// A human-readable message describing what went wrong.
message: string,

/// Returns a human-readable message describing the parsing error.
message: func() -> string;
/// The text range where the error occurred in the source code.
text-range: text-range,
}

/// The output of a parsing operation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,7 @@ impl IntoFFI<ffi::QueryError> for rust::QueryError {
fn _into_ffi(self) -> ffi::QueryError {
ffi::QueryError {
message: self.message,
line: self.line.try_into().unwrap(),
column: self.column.try_into().unwrap(),
text_range: self.text_range._into_ffi(),
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
use crate::wasm_crate::utils::{define_wrapper, FromFFI, IntoFFI};

mod ffi {
pub use crate::wasm_crate::bindgen::exports::nomic_foundation::slang::cst::{
Cursor, Node, TextRange,
};
pub use crate::wasm_crate::bindgen::exports::nomic_foundation::slang::cst::{Cursor, Node};
pub use crate::wasm_crate::bindgen::exports::nomic_foundation::slang::parser::{
Guest, GuestParseError, GuestParseOutput, GuestParser, NonterminalKind, ParseError,
ParseErrorBorrow, ParseOutput, ParseOutputBorrow, Parser, ParserBorrow,
Guest, GuestParseOutput, GuestParser, NonterminalKind, ParseError, ParseOutput,
ParseOutputBorrow, Parser, ParserBorrow,
};
}

Expand All @@ -16,7 +14,6 @@ mod rust {

impl ffi::Guest for crate::wasm_crate::World {
type Parser = ParserWrapper;
type ParseError = ParseErrorWrapper;
type ParseOutput = ParseOutputWrapper;
}

Expand Down Expand Up @@ -49,19 +46,19 @@ define_wrapper! { Parser {

//================================================
//
// resource parse-error
// record parse-error
//
//================================================

define_wrapper! { ParseError {
fn text_range(&self) -> ffi::TextRange {
self._borrow_ffi().text_range()._into_ffi()
}

fn message(&self) -> String {
self._borrow_ffi().message()
impl IntoFFI<ffi::ParseError> for rust::ParseError {
#[inline]
fn _into_ffi(self) -> ffi::ParseError {
ffi::ParseError {
message: self.message(),
text_range: self.text_range()._into_ffi(),
}
}
} }
}

//================================================
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ export const Parser = wasm.parser.Parser;
/** {@inheritDoc wasm.parser.Parser} */
export type Parser = wasm.parser.Parser;

/** {@inheritDoc wasm.parser.ParseError} */
export const ParseError = wasm.parser.ParseError;
/** {@inheritDoc wasm.parser.ParseError} */
export type ParseError = wasm.parser.ParseError;

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions crates/metaslang/cst/src/query/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::rc::Rc;

use crate::kinds::{BaseKind, KindTypes, NodeKind};
use crate::query::{CaptureQuantifier, QueryError};
use crate::text_index::TextIndex;

#[derive(Clone, Debug)]
pub struct Query<T: KindTypes> {
Expand All @@ -24,8 +25,7 @@ impl<T: KindTypes> Query<T> {
if capture_quantifiers.contains_key(&capture.name) {
return Err(QueryError {
message: format!("Capture name '{}' used more than once", capture.name),
line: 0,
column: 0,
text_range: TextIndex::ZERO..TextIndex::ZERO,
});
}
capture_quantifiers.insert(capture.name.clone(), quantifier);
Expand Down Expand Up @@ -69,8 +69,7 @@ impl<T: KindTypes> Query<T> {
return Err(QueryError {
message: "Quantification over quantification is not allowed"
.to_string(),
line: 0,
column: 0,
text_range: TextIndex::ZERO..TextIndex::ZERO,
})
}
};
Expand Down
43 changes: 13 additions & 30 deletions crates/metaslang/cst/src/query/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,15 @@ use super::model::{
OptionalASTNode, SequenceASTNode,
};
use crate::kinds::{BaseKind, KindTypes, NodeKind, TerminalKindExtensions};
use crate::text_index::TextIndex;
use crate::text_index::{TextIndex, TextRange};

// ----------------------------------------------------------------------------
// Parse errors

#[derive(Clone, Debug, Error)]
pub struct QueryError {
pub message: String,
pub line: usize,
pub column: usize,
pub text_range: TextRange,
}

impl std::fmt::Display for QueryError {
Expand Down Expand Up @@ -128,36 +127,20 @@ pub(super) fn parse_query<T: KindTypes>(input: &str) -> Result<ASTNode<T>, Query
.parse(input)
.finish()
.map(|(_, query)| query)
.map_err(|e| {
let text_index = compute_row_and_column(e.errors[0].0, input);
QueryError {
message: e.to_string(),
line: text_index.line,
column: text_index.column,
}
.map_err(|e| QueryError {
message: e.to_string(),
text_range: compute_error_location(input, e.errors[0].0),
})
}

fn compute_row_and_column(target: &str, input: &str) -> TextIndex {
let target_offset = input.offset(target);
let mut text_index = TextIndex::ZERO;
let mut from_iter = input.chars();
let Some(mut c) = from_iter.next() else {
return text_index;
};
let mut next_c = from_iter.next();
loop {
if text_index.utf8 >= target_offset {
break;
}
text_index.advance(c, next_c.as_ref());
c = match next_c {
Some(ch) => ch,
None => break,
};
next_c = from_iter.next();
}
text_index
fn compute_error_location(input: &str, target: &str) -> TextRange {
let mut start = TextIndex::ZERO;
start.advance_str(&input[..input.offset(target)]);

let mut end = start;
end.advance_str(target);

TextRange { start, end }
}

fn parse_matcher_alternatives<T: KindTypes>(
Expand Down
Loading

0 comments on commit 2b5df65

Please sign in to comment.