Skip to content

Commit

Permalink
bumped grammar version: updated features + added array initializer ex…
Browse files Browse the repository at this point in the history
…pression
  • Loading branch information
SpontanCombust committed Aug 14, 2024
1 parent 0312b58 commit 6bc1a6f
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 14 deletions.
23 changes: 15 additions & 8 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ thiserror.workspace = true
shrinkwraprs.workspace = true
ropey.workspace = true
lsp-types.workspace = true
tree-sitter = "0.20"
tree-sitter = ">=0.22.6"
encoding_rs_io = "0.1"

[dependencies.tree-sitter-witcherscript]
git = "https://github.com/SpontanCombust/tree-sitter-witcherscript.git"
tag = "v0.11.0"
tag = "v0.12.0"
77 changes: 76 additions & 1 deletion crates/core/src/ast/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ mod tags {
pub struct BinaryOperationExpression;
pub struct AssignmentOperationExpression;
pub struct TernaryConditionalExpression;
pub struct ArrayInitializerExpression;
pub struct ExpressionStatement;
}

Expand Down Expand Up @@ -1007,6 +1008,69 @@ impl SyntaxNodeTraversal for TernaryConditionalExpressionNode<'_> {



pub type ArrayInitializerExpressionNode<'script> = SyntaxNode<'script, tags::ArrayInitializerExpression>;

impl NamedSyntaxNode for ArrayInitializerExpressionNode<'_> {
const NODE_KIND: &'static str = "array_init_expr";
}

impl<'script> ArrayInitializerExpressionNode<'script> {
pub fn iter(&self) -> impl Iterator<Item = ExpressionNode<'script>> {
self.named_children().map(|ch| ch.unsafe_into())
}
}

impl Debug for ArrayInitializerExpressionNode<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_maybe_alternate_named(
&format!("ArrayInitializerExpression {}", self.range().debug()),
&self.iter().collect::<Vec<_>>()
)
}
}

impl<'script> TryFrom<AnyNode<'script>> for ArrayInitializerExpressionNode<'script> {
type Error = ();

fn try_from(value: AnyNode<'script>) -> Result<Self, Self::Error> {
if value.tree_node.kind() == Self::NODE_KIND {
Ok(value.unsafe_into())
} else {
Err(())
}
}
}

impl SyntaxNodeTraversal for ArrayInitializerExpressionNode<'_> {
fn accept<V: SyntaxNodeVisitor>(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_array_initializer_expr(self, ctx);

if tp.any() {
ctx.push(TraversalContext::ArrayInitializerExpression);

for ch in self.children_detailed().must_be_named(true) {
match ch {
Ok((item, _)) if tp.traverse_items => {
let item: ExpressionNode = item.unsafe_into();

item.accept(visitor, ctx);
},
Err(e) if tp.traverse_errors => {
e.accept(visitor, ctx);
},
_ => {}
}
}

ctx.pop();
}

visitor.exit_array_initializer_expr(self, ctx);
}
}



// Represents the unnamed $._expr node
#[derive(Clone)]
pub enum Expression<'script> {
Expand All @@ -1026,6 +1090,7 @@ pub enum Expression<'script> {
BinaryOperation(BinaryOperationExpressionNode<'script>),
AssignmentOperation(AssignmentOperationExpressionNode<'script>),
TernaryConditional(TernaryConditionalExpressionNode<'script>),
ArrayInitializer(ArrayInitializerExpressionNode<'script>)
}

impl Debug for Expression<'_> {
Expand All @@ -1047,6 +1112,7 @@ impl Debug for Expression<'_> {
Self::BinaryOperation(n) => f.debug_maybe_alternate(n),
Self::AssignmentOperation(n) => f.debug_maybe_alternate(n),
Self::TernaryConditional(n) => f.debug_maybe_alternate(n),
Self::ArrayInitializer(n) => f.debug_maybe_alternate(n),
}
}
}
Expand Down Expand Up @@ -1078,6 +1144,7 @@ impl<'script> ExpressionNode<'script> {
LiteralStringNode::NODE_KIND |
LiteralNameNode::NODE_KIND |
LiteralNullNode::NODE_KIND => Expression::Literal(self.unsafe_into()),
ArrayInitializerExpressionNode::NODE_KIND => Expression::ArrayInitializer(self.unsafe_into()),
_ => panic!("Unknown expression type: {} {}", self.tree_node.kind(), self.range().debug())
}
}
Expand Down Expand Up @@ -1119,7 +1186,8 @@ impl<'script> TryFrom<AnyNode<'script>> for ExpressionNode<'script> {
LiteralBoolNode::NODE_KIND |
LiteralStringNode::NODE_KIND |
LiteralNameNode::NODE_KIND |
LiteralNullNode::NODE_KIND => Ok(value.unsafe_into()),
LiteralNullNode::NODE_KIND |
ArrayInitializerExpressionNode::NODE_KIND => Ok(value.unsafe_into()),
_ => Err(())
}
}
Expand Down Expand Up @@ -1221,6 +1289,12 @@ impl<'script> From<TernaryConditionalExpressionNode<'script>> for ExpressionNode
}
}

impl<'script> From<ArrayInitializerExpressionNode<'script>> for ExpressionNode<'script> {
fn from(value: ArrayInitializerExpressionNode<'script>) -> Self {
value.unsafe_into()
}
}

impl SyntaxNodeTraversal for ExpressionNode<'_> {
fn accept<V: SyntaxNodeVisitor>(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
match self.clone().value() {
Expand All @@ -1240,6 +1314,7 @@ impl SyntaxNodeTraversal for ExpressionNode<'_> {
Expression::BinaryOperation(n) => n.accept(visitor, ctx),
Expression::AssignmentOperation(n) => n.accept(visitor, ctx),
Expression::TernaryConditional(n) => n.accept(visitor, ctx),
Expression::ArrayInitializer(n) => n.accept(visitor, ctx),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/core/src/ast/traversal/contexts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ pub enum TraversalContext {
TernaryConditionalExpressionCond,
TernaryConditionalExpressionConseq,
TernaryConditionalExpressionAlt,
ArrayInitializerExpression,

Error
}
Expand Down
34 changes: 34 additions & 0 deletions crates/core/src/ast/traversal/policies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,40 @@ impl BitAnd for TernaryConditionalExpressionTraversalPolicy {
}


#[derive(Debug, Clone)]
pub struct ArrayInitializerExpressionTraversalPolicy {
pub traverse_items: bool,
pub traverse_errors: bool
}

impl TraversalPolicy for ArrayInitializerExpressionTraversalPolicy {
#[inline(always)]
fn default_to(value: bool) -> Self {
Self {
traverse_items: value,
traverse_errors: value
}
}

#[inline]
fn any(&self) -> bool {
self.traverse_items ||
self.traverse_errors
}
}

impl BitAnd for ArrayInitializerExpressionTraversalPolicy {
type Output = Self;

fn bitand(self, rhs: Self) -> Self::Output {
Self {
traverse_items: self.traverse_items && rhs.traverse_items,
traverse_errors: self.traverse_errors && rhs.traverse_errors
}
}
}




#[derive(Debug, Clone)]
Expand Down
10 changes: 10 additions & 0 deletions crates/core/src/ast/traversal/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,16 @@ pub trait SyntaxNodeVisitor {
/// Called after visiting a ternary conditional expression and possibly also children nodes specified in traversal policy.
fn exit_ternary_cond_expr(&mut self, n: &TernaryConditionalExpressionNode, ctx: &TraversalContextStack) {}

/// Called when visiting an array initializer expression.
/// Array initializer can be used in the `default` statement context to initialize a member array.
/// The syntax for it is like in C++:
/// ```js
/// default myArray: array<string> = {"item1", "item2", "item3"};
/// ```
fn visit_array_initializer_expr(&mut self, n: &ArrayInitializerExpressionNode, ctx: &TraversalContextStack) -> ArrayInitializerExpressionTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting an array initializer expression and possibly also children nodes specified in traversal policy.
fn exit_array_initializer_expr(&mut self, n: &ArrayInitializerExpressionNode, ctx: &TraversalContextStack) {}




Expand Down
10 changes: 10 additions & 0 deletions crates/core/src/ast/traversal/visitor_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,16 @@ impl<'a> SyntaxNodeVisitor for SyntaxNodeVisitorChain<'a> {
self.chain_visit(move |link| link.visit_virtual_parent_expr(n, ctx))
}

#[inline]
fn visit_array_initializer_expr(&mut self, n: &ArrayInitializerExpressionNode, ctx: &TraversalContextStack) -> ArrayInitializerExpressionTraversalPolicy {
self.chain_visit_traversable(move |link| link.visit_array_initializer_expr(n, ctx))
}

#[inline]
fn exit_array_initializer_expr(&mut self, n: &ArrayInitializerExpressionNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_array_initializer_expr(n, ctx))
}


#[inline]
fn visit_annotation(&mut self, n: &AnnotationNode, ctx: &TraversalContextStack) -> AnnotationTraversalPolicy {
Expand Down
2 changes: 1 addition & 1 deletion crates/core/src/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl Script {
use ScriptError::*;

let mut parser = Parser::new();
parser.set_language(tree_sitter_witcherscript::language()).map_err(ParserInitError)?;
parser.set_language(&tree_sitter_witcherscript::language()).map_err(ParserInitError)?;

let parse_tree = parser.parse_with(&mut |byte, _| {
if byte <= rope.len_bytes() {
Expand Down
4 changes: 2 additions & 2 deletions crates/core/src/syntax_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,15 +336,15 @@ impl<'script> Iterator for SyntaxNodeChildren<'script> {
pub struct SyntaxNodeFieldChildren<'script> {
cursor: ts::TreeCursor<'script>,
any_children_left: bool,
field_id: u16
field_id: std::num::NonZeroU16
}

impl<'script> SyntaxNodeFieldChildren<'script> {
fn new(tree_node: &ts::Node<'script>, cursor: Option<ts::TreeCursor<'script>>, field_name: &str) -> Self {
let mut cursor = cursor.unwrap_or(tree_node.walk());
let any_children_left = cursor.goto_first_child();

let field_id = tree_sitter_witcherscript::language()
let field_id = tree_node.language()
.field_id_for_name(field_name)
.expect(&format!("Unknown field name {}", field_name));

Expand Down
1 change: 1 addition & 0 deletions crates/core/src/syntax_node_any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ impl<'script> SyntaxNodeTraversal for AnyNode<'script> {
BinaryOperationExpressionNode::NODE_KIND => { let n: BinaryOperationExpressionNode = n.unsafe_into(); n.accept(visitor, ctx); },
AssignmentOperationExpressionNode::NODE_KIND => { let n: AssignmentOperationExpressionNode = n.unsafe_into(); n.accept(visitor, ctx); },
TernaryConditionalExpressionNode::NODE_KIND => { let n: TernaryConditionalExpressionNode = n.unsafe_into(); n.accept(visitor, ctx); },
ArrayInitializerExpressionNode::NODE_KIND => { let n: ArrayInitializerExpressionNode = n.unsafe_into(); n.accept(visitor, ctx); },


RootNode::NODE_KIND => { let n: RootNode = n.unsafe_into(); n.accept(visitor, ctx); },
Expand Down

0 comments on commit 6bc1a6f

Please sign in to comment.