Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose query api to typescript #761

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 19 additions & 18 deletions crates/codegen/parser/generator/src/rust_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,9 @@ impl RustGenerator {
)?;
}

for (src_file, destination_file) in &[
("query/mod_for_destination.rs", "query/mod.rs"),
("mod_for_destination.rs", "mod.rs"),
] {
#[allow(clippy::single_element_loop)]
// kept in case there is once again more than one of these
for (src_file, destination_file) in &[("mod_for_destination.rs", "mod.rs")] {
codegen.copy_file(
runtime_dir.join(src_file),
output_dir.join(destination_file),
Expand All @@ -129,30 +128,32 @@ impl RustGenerator {
"cst.rs",
"cursor.rs",
"lexer.rs",
"parse_error.rs",
"parse_output.rs",
"query/engine.rs",
"query/model.rs",
"query/parser.rs",
"text_index.rs",
"napi_interface/cst.rs",
"napi_interface/cursor.rs",
"napi_interface/mod.rs",
"napi_interface/parse_error.rs",
"napi_interface/parse_output.rs",
"napi_interface/query.rs",
"napi_interface/text_index.rs",
"napi_interface/mod.rs",
"parser_support/mod.rs",
"parse_error.rs",
"parse_output.rs",
"parser_support/choice_helper.rs",
"parser_support/context.rs",
"parser_support/parser_function.rs",
"parser_support/mod.rs",
"parser_support/optional_helper.rs",
"parser_support/sequence_helper.rs",
"parser_support/repetition_helper.rs",
"parser_support/choice_helper.rs",
"parser_support/precedence_helper.rs",
"parser_support/parser_function.rs",
"parser_support/parser_result.rs",
"parser_support/precedence_helper.rs",
"parser_support/recovery.rs",
"parser_support/separated_helper.rs",
"parser_support/repetition_helper.rs",
"parser_support/scanner_macros.rs",
"parser_support/separated_helper.rs",
"parser_support/sequence_helper.rs",
"query/engine.rs",
"query/mod.rs",
"query/model.rs",
"query/parser.rs",
"text_index.rs",
] {
codegen.copy_file(runtime_dir.join(file), output_dir.join(file))?;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use text_index::{TextIndex, TextRange};
use crate::napi_interface::{cst, text_index, FieldName, RuleKind, RustCursor, TokenKind};

#[napi(namespace = "cursor")]
pub struct Cursor(Box<RustCursor>);
pub struct Cursor(pub(super) Box<RustCursor>);
OmarTawfik marked this conversation as resolved.
Show resolved Hide resolved

impl From<RustCursor> for Cursor {
fn from(value: RustCursor) -> Self {
Expand Down
3 changes: 3 additions & 0 deletions crates/codegen/parser/runtime/src/napi_interface/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ pub mod cst;
pub mod cursor;
pub mod parse_error;
pub mod parse_output;
pub mod query;
pub mod text_index;

type RustCursor = crate::cursor::Cursor;
type RustNamedNode = crate::cst::NamedNode;
type RustNode = crate::cst::Node;
type RustParseError = crate::parse_error::ParseError;
type RustParseOutput = crate::parse_output::ParseOutput;
type RustQuery = crate::query::Query;
type RustQueryResultIterator = crate::query::QueryResultIterator;
type RustRuleNode = crate::cst::RuleNode;
type RustTextIndex = crate::text_index::TextIndex;
type RustTextRange = crate::text_index::TextRange;
Expand Down
92 changes: 92 additions & 0 deletions crates/codegen/parser/runtime/src/napi_interface/query.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// NAPI-exposed functions have to accept owned values
#![allow(clippy::needless_pass_by_value)]
// The functions are meant to be definitions for export, so they're not really used
#![allow(clippy::return_self_not_must_use)]

use napi::{Env, JsObject};
use napi_derive::napi;

use crate::napi_interface::cursor::Cursor;
use crate::napi_interface::{RustQuery, RustQueryResultIterator};

#[napi(namespace = "query")]
pub struct Query(RustQuery);
OmarTawfik marked this conversation as resolved.
Show resolved Hide resolved

impl From<RustQuery> for Query {
fn from(value: RustQuery) -> Self {
Self(value)
}
}

#[napi(namespace = "query")]
impl Query {
#[napi(factory, catch_unwind)]
pub fn parse(text: String) -> napi::Result<Query> {
RustQuery::parse(text.as_str()).map_or_else(
|err| Err(napi::Error::from_reason(err)),
|query| Ok(query.into()),
)
}

#[napi(getter, catch_unwind)]
pub fn text(&self) -> String {
self.0.to_string()
}
}

#[napi(namespace = "query")]
pub struct QueryResultIterator(RustQueryResultIterator);

#[napi(object, namespace = "query")]
pub struct QueryResult {
pub query_number: u32,
#[napi(ts_type = "{ [key: string]: cursor.Cursor[] }")]
pub bindings: JsObject,
}
OmarTawfik marked this conversation as resolved.
Show resolved Hide resolved

impl From<RustQueryResultIterator> for QueryResultIterator {
fn from(value: RustQueryResultIterator) -> Self {
Self(value)
}
}

#[napi(namespace = "query")]
impl QueryResultIterator {
#[napi(catch_unwind)]
pub fn next(&mut self, env: Env) -> napi::Result<Option<QueryResult>> {
match self.0.next() {
Some(result) => {
#[allow(clippy::cast_possible_truncation)]
let query_number = result.query_number as u32;
let mut bindings = env.create_object()?;
// transer all of the bindings eagerly on the assumption
// that they've all been explicitly requested.
for (key, value) in result.bindings {
bindings.set_named_property(
&key,
value.into_iter().map(|x| x.into()).collect::<Vec<Cursor>>(),
)?;
}
Ok(Some(QueryResult {
query_number,
bindings,
}))
}
None => Ok(None),
}
}
}

#[napi(namespace = "cursor")]
impl Cursor {
#[napi(ts_return_type = "query.QueryResultIterator", catch_unwind)]
pub fn query(
&self,
#[napi(ts_arg_type = "Array<query.Query>")] queries: Vec<&Query>,
) -> QueryResultIterator {
self.0
.clone()
.query(queries.into_iter().map(|x| x.0.clone()).collect())
.into()
}
}
9 changes: 3 additions & 6 deletions crates/codegen/parser/runtime/src/query/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
mod engine;
pub mod model;
mod model;
mod parser;

#[cfg(test)]
mod engine_tests;

#[cfg(test)]
mod parser_tests;
pub use engine::{QueryResult, QueryResultIterator};
pub use model::Query;

This file was deleted.

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.

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.

14 changes: 14 additions & 0 deletions crates/solidity/outputs/npm/package/src/generated/index.d.ts

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.

1 change: 1 addition & 0 deletions crates/solidity/outputs/npm/package/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export * as kinds from "./kinds";
export * as language from "./language";
export * as parse_error from "./parse_error";
export * as parse_output from "./parse_output";
export * as query from "./query";
export * as text_index from "./text_index";
4 changes: 4 additions & 0 deletions crates/solidity/outputs/npm/package/src/query/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import * as generated from "../generated";

export const Query = generated.query.Query;
export type Query = generated.query.Query;

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

Loading