Skip to content

Commit

Permalink
feat: refactor and improve all over the place
Browse files Browse the repository at this point in the history
  • Loading branch information
psteinroe committed Oct 1, 2023
1 parent 06b5836 commit 2b7729d
Show file tree
Hide file tree
Showing 9 changed files with 429 additions and 292 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use pg_query_proto_parser::{FieldType, Node, ProtoParser};
use proc_macro2::{Ident, TokenStream};
use quote::{format_ident, quote};

pub fn get_children_mod(_item: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
pub fn get_nodes_mod(_item: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
let parser = ProtoParser::new("./libpg_query/protobuf/pg_query.proto");
let proto_file = parser.parse();

Expand All @@ -16,16 +16,18 @@ pub fn get_children_mod(_item: proc_macro2::TokenStream) -> proc_macro2::TokenSt
use std::collections::VecDeque;

#[derive(Debug, Clone)]
pub struct ChildrenNode {
pub struct Node {
pub node: NodeEnum,
pub depth: i32,
pub path: String,
}

/// Returns all children of the node, recursively
/// location is resolved manually
pub fn get_children(node: &NodeEnum, text: String, current_depth: i32) -> Vec<ChildrenNode> {
let mut nodes: Vec<ChildrenNode> = vec![];
pub fn get_nodes(node: &NodeEnum, text: String, current_depth: i32) -> Vec<Node> {
let mut nodes: Vec<Node> = vec![
Node { node: node.to_owned(), depth: current_depth, path: "0".to_string() }
];
// Node, depth, path
let mut stack: VecDeque<(NodeEnum, i32, String)> =
VecDeque::from(vec![(node.to_owned(), current_depth, "0".to_string())]);
Expand All @@ -37,7 +39,7 @@ pub fn get_children_mod(_item: proc_macro2::TokenStream) -> proc_macro2::TokenSt
let path = path.clone() + "." + child_ctr.to_string().as_str();
child_ctr = child_ctr + 1;
stack.push_back((c.to_owned(), current_depth, path.clone()));
nodes.push(ChildrenNode {
nodes.push(Node {
node: c,
depth: current_depth,
path: path.clone(),
Expand Down
8 changes: 4 additions & 4 deletions crates/codegen/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
mod get_children;
mod get_location;
mod get_nodes;
mod syntax_kind;

use get_children::get_children_mod;
use get_location::get_location_mod;
use get_nodes::get_nodes_mod;
use syntax_kind::syntax_kind_mod;

#[proc_macro]
pub fn get_children(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
get_children_mod(item.into()).into()
pub fn get_nodes(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
get_nodes_mod(item.into()).into()
}

#[proc_macro]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use codegen::get_children;
use codegen::get_nodes;

get_children!();
get_nodes!();

#[cfg(test)]
mod tests {
use crate::get_children_codegen::get_children;
use crate::get_nodes_codegen::get_nodes;

#[test]
fn test_get_children() {
fn test_get_nodes() {
let input = "with c as (insert into contact (id) values ('id')) select * from c;";

let pg_query_root = match pg_query::parse(input) {
Expand All @@ -24,7 +24,7 @@ mod tests {
Err(_) => None,
};

let children = get_children(&pg_query_root.unwrap(), input.to_string(), 1);
assert_eq!(children.len(), 13);
let nodes = get_nodes(&pg_query_root.unwrap(), input.to_string(), 1);
assert_eq!(nodes.len(), 14);
}
}
4 changes: 1 addition & 3 deletions crates/parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,15 @@
//! To see how these drawbacks are mitigated, see the `statement.rs` and the `source_file.rs` module.
mod ast_node;
mod get_children_codegen;
mod get_location_codegen;
mod get_nodes_codegen;
mod parser;
mod resolve_tokens;
mod sibling_token;
mod source_parser;
mod statement_parser;
mod syntax_error;
mod syntax_kind_codegen;
mod syntax_node;

pub use crate::parser::{Parse, Parser};
pub use crate::syntax_kind_codegen::SyntaxKind;
pub use crate::syntax_node::{SyntaxElement, SyntaxNode, SyntaxToken};
72 changes: 4 additions & 68 deletions crates/parser/src/parser.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use cstree::syntax::ResolvedNode;
use cstree::{build::GreenNodeBuilder, text::TextRange};
use log::debug;
use pg_query::NodeEnum;

use crate::ast_node::RawStmt;
use crate::syntax_error::SyntaxError;
use crate::syntax_kind_codegen::SyntaxKind;
use crate::syntax_node::SyntaxNode;

/// Main parser that controls the cst building process, and collects errors and statements
/// Main parser that exposes the `cstree` api, and collects errors and statements
#[derive(Debug)]
pub struct Parser {
/// The cst builder
Expand All @@ -17,16 +16,9 @@ pub struct Parser {
errors: Vec<SyntaxError>,
/// The pg_query statements representing the abtract syntax tree
stmts: Vec<RawStmt>,
/// The current checkpoint depth, if any
checkpoint: Option<i32>,
/// Whether the parser is currently parsing a flat node
is_parsing_flat_node: bool,
/// Keeps track of currently open nodes
/// Latest opened is last
open_nodes: Vec<(SyntaxKind, i32)>,
}

/// Result of parsing
/// Result of Building
#[derive(Debug)]
pub struct Parse {
/// The concrete syntax tree
Expand All @@ -43,72 +35,16 @@ impl Parser {
inner: GreenNodeBuilder::new(),
errors: Vec::new(),
stmts: Vec::new(),
checkpoint: None,
is_parsing_flat_node: false,
open_nodes: Vec::new(),
}
}

/// close all nodes until the specified depth is reached
pub fn close_until_depth(&mut self, depth: i32) {
debug!("close until depth {}", depth);
if self.open_nodes.is_empty() || self.get_current_depth() < depth {
return;
}
loop {
if self.open_nodes.is_empty() || self.get_current_depth() < depth {
break;
}
self.finish_node();
}
}

fn get_current_depth(&self) -> i32 {
self.open_nodes[self.open_nodes.len() - 1].1
}

/// set a checkpoint at current depth
///
/// if `is_parsing_flat_node` is true, all tokens parsed until this checkpoint is closed will be applied immediately
pub fn set_checkpoint(&mut self) {
assert!(
self.checkpoint.is_none(),
"Must close previouos checkpoint before setting new one"
);
self.checkpoint = Some(self.get_current_depth());
}

/// close all nodes until checkpoint depth is reached
pub fn close_checkpoint(&mut self) {
if self.checkpoint.is_some() {
self.close_until_depth(self.checkpoint.unwrap());
}
self.checkpoint = None;
self.is_parsing_flat_node = false;
}

/// start a new node of `SyntaxKind` at `depth`
/// handles closing previous nodes if necessary
pub fn start_node_at(&mut self, kind: SyntaxKind, depth: i32) {
debug!("starting node at depth {} {:?}", depth, kind);
// close until target depth
self.close_until_depth(depth);

self.open_nodes.push((kind, depth));
debug!("start node {:?}", kind);
/// start a new node of `SyntaxKind`
pub fn start_node(&mut self, kind: SyntaxKind) {
self.inner.start_node(kind);
}

/// finish current node
pub fn finish_node(&mut self) {
debug!("finish_node");

let n = self.open_nodes.pop();
if n.is_none() {
panic!("No node to finish");
}

debug!("finish node {:?}", n.unwrap().0);
self.inner.finish_node();
}

Expand Down
Loading

0 comments on commit 2b7729d

Please sign in to comment.