mirror of
https://github.com/enso-org/enso.git
synced 2025-01-02 01:02:05 +03:00
Add Token node kind in SpanTree (https://github.com/enso-org/ide/pull/897)
Original commit: c7edf73672
This commit is contained in:
parent
13f24f9148
commit
f8dd24d745
@ -151,6 +151,7 @@ impl<'a,T> Implementation for node::Ref<'a,T> {
|
||||
);
|
||||
root.set_traversing(&self.ast_crumbs,new_ast?)
|
||||
})),
|
||||
node::Kind::Token => None,
|
||||
_ => match &self.ast_crumbs.last() {
|
||||
// Operators should be treated in a special way - setting functions in place in
|
||||
// a operator should replace Infix with Prefix with two applications.
|
||||
@ -366,8 +367,12 @@ mod test {
|
||||
, Case{expr:"f a" , span:2..3 , expected: &[Set] }
|
||||
, Case{expr:"if a then b", span:3..4 , expected: &[Set] }
|
||||
, Case{expr:"if a then b", span:10..11, expected: &[Set] }
|
||||
, Case{expr:"(a + b)" , span:0..1 , expected: &[] }
|
||||
, Case{expr:"[a,b]" , span:0..1 , expected: &[] }
|
||||
, Case{expr:"[a,b]" , span:4..5 , expected: &[] }
|
||||
, Case{expr:"(a + b + c)", span:5..6 , expected: &[Set,Erase] }
|
||||
, Case{expr:"(a" , span:1..2 , expected: &[Set] }
|
||||
, Case{expr:"(a" , span:0..1 , expected: &[] }
|
||||
, Case{expr:"(a + b + c" , span:5..6 , expected: &[Set,Erase] }
|
||||
];
|
||||
let parser = Parser::new_or_panic();
|
||||
|
@ -380,14 +380,24 @@ fn generate_node_for_known_match<T:Payload>
|
||||
fn generate_children_from_segment<T:Payload>
|
||||
(gen:&mut ChildGenerator<T>, index:usize, segment:&MacroMatchSegment<Ast>, context:&impl Context)
|
||||
-> FallibleResult {
|
||||
let children_kind = node::Kind::argument();
|
||||
gen.spacing(segment.head.len());
|
||||
|
||||
// generate child for head
|
||||
let ast = segment.head.clone_ref();
|
||||
let segment_crumb = ast::crumbs::SegmentMatchCrumb::Head;
|
||||
let ast_crumb = ast::crumbs::MatchCrumb::Segs {val:segment_crumb, index};
|
||||
let located_ast = Located::new(ast_crumb,ast);
|
||||
gen.generate_ast_node(located_ast,node::Kind::Token,context)?;
|
||||
|
||||
for macros::AstInPattern {ast,crumbs} in macros::all_ast_nodes_in_pattern(&segment.body) {
|
||||
let child_kind = match crumbs.last() {
|
||||
Some(ast::crumbs::PatternMatchCrumb::Tok) => node::Kind::Token,
|
||||
_ => node::Kind::argument().into(),
|
||||
};
|
||||
gen.spacing(ast.off);
|
||||
let segment_crumb = ast::crumbs::SegmentMatchCrumb::Body {val:crumbs};
|
||||
let ast_crumb = ast::crumbs::MatchCrumb::Segs{val:segment_crumb, index};
|
||||
let located_ast = Located::new(ast_crumb,ast.wrapped);
|
||||
gen.generate_ast_node(located_ast,children_kind.clone(),context)?;
|
||||
gen.generate_ast_node(located_ast,child_kind,context)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -426,7 +436,13 @@ fn generate_children_from_ambiguous<T:Payload>
|
||||
, context : &impl Context
|
||||
) -> FallibleResult {
|
||||
let children_kind = node::Kind::argument();
|
||||
gen.spacing(segment.head.len());
|
||||
// generate child for head
|
||||
let ast = segment.head.clone_ref();
|
||||
let segment_crumb = ast::crumbs::AmbiguousSegmentCrumb::Head;
|
||||
let ast_crumb = ast::crumbs::AmbiguousCrumb {field:segment_crumb, index};
|
||||
let located_ast = Located::new(ast_crumb,ast);
|
||||
gen.generate_ast_node(located_ast,node::Kind::Token,context)?;
|
||||
|
||||
if let Some(sast) = &segment.body {
|
||||
gen.spacing(sast.off);
|
||||
let field = ast::crumbs::AmbiguousSegmentCrumb::Body;
|
||||
@ -745,17 +761,17 @@ mod test {
|
||||
|
||||
// Check the other fields
|
||||
clear_expression_ids(&mut tree.root);
|
||||
let if_then_else_cr = vec![Seq { right: false }, Or, Build];
|
||||
let parens_cr = vec![Seq { right: false }, Or, Or, Build];
|
||||
let segment_body_crumbs = |index:usize, pattern_crumb:&Vec<PatternMatchCrumb>| {
|
||||
let val = ast::crumbs::SegmentMatchCrumb::Body {val:pattern_crumb.clone()};
|
||||
ast::crumbs::MatchCrumb::Segs {val,index}
|
||||
};
|
||||
let seq = Seq {right:false};
|
||||
let if_then_else_cr = vec![seq,Or,Build];
|
||||
let parens_cr = vec![seq,Or,Or,Build];
|
||||
|
||||
let expected = TreeBuilder::new(29)
|
||||
.add_leaf(0,2,node::Kind::Token,segment_head_crumbs(0))
|
||||
.add_leaf(3,3,node::Kind::argument(),segment_body_crumbs(0,&if_then_else_cr))
|
||||
.add_leaf(7,4,node::Kind::Token,segment_head_crumbs(1))
|
||||
.add_child(12,9,node::Kind::argument(),segment_body_crumbs(1,&if_then_else_cr))
|
||||
.add_child(0,7,node::Kind::Operation,PrefixCrumb::Func)
|
||||
.add_leaf(0,1,node::Kind::Token,segment_head_crumbs(0))
|
||||
.add_child(1,5,node::Kind::argument(),segment_body_crumbs(0,&parens_cr))
|
||||
.add_empty_child(0,BeforeTarget)
|
||||
.add_leaf(0,1,node::Kind::this(),InfixCrumb::LeftOperand)
|
||||
@ -764,12 +780,46 @@ mod test {
|
||||
.add_leaf(4,1,node::Kind::argument(),InfixCrumb::RightOperand)
|
||||
.add_empty_child(5,Append)
|
||||
.done()
|
||||
.add_leaf(6,1,node::Kind::Token,segment_head_crumbs(1))
|
||||
.done()
|
||||
.add_empty_child(8,BeforeTarget)
|
||||
.add_leaf(8,1,node::Kind::this(),PrefixCrumb::Arg)
|
||||
.add_empty_child(9,Append)
|
||||
.done()
|
||||
.add_leaf(27,2,node::Kind::argument(),segment_body_crumbs(2,&if_then_else_cr))
|
||||
.add_leaf(22,4,node::Kind::Token,segment_head_crumbs(2))
|
||||
.add_child(27,2,node::Kind::argument(),segment_body_crumbs(2,&if_then_else_cr))
|
||||
.add_leaf(0,1,node::Kind::Token,segment_head_crumbs(0))
|
||||
.add_leaf(1,1,node::Kind::Token,segment_head_crumbs(1))
|
||||
.done()
|
||||
.build();
|
||||
|
||||
assert_eq!(expected,tree);
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn generating_span_tree_from_matched_list_macro() {
|
||||
use PatternMatchCrumb::*;
|
||||
|
||||
let parser = Parser::new_or_panic();
|
||||
let expression = "[a,b]";
|
||||
let ast = parser.parse_line(expression).unwrap();
|
||||
let mut tree = ast.generate_tree(&context::Empty).unwrap() : SpanTree;
|
||||
|
||||
// Check the other fields
|
||||
clear_expression_ids(&mut tree.root);
|
||||
let left_seq = Seq {right:false};
|
||||
let right_seq = Seq {right:true};
|
||||
let many = Many {index:0};
|
||||
let first_element_cr = vec![left_seq,Or,Or,left_seq,Build];
|
||||
let second_element_cr = vec![left_seq,Or,Or,right_seq,many,right_seq,Build];
|
||||
let comma_cr = vec![left_seq,Or,Or,right_seq,many,left_seq,Tok];
|
||||
|
||||
let expected = TreeBuilder::new(5)
|
||||
.add_leaf(0,1,node::Kind::Token,segment_head_crumbs(0))
|
||||
.add_leaf(1,1,node::Kind::argument(),segment_body_crumbs(0,&first_element_cr))
|
||||
.add_leaf(2,1,node::Kind::Token,segment_body_crumbs(0,&comma_cr))
|
||||
.add_leaf(3,1,node::Kind::argument(),segment_body_crumbs(0,&second_element_cr))
|
||||
.add_leaf(4,1,node::Kind::Token,segment_head_crumbs(1))
|
||||
.build();
|
||||
|
||||
assert_eq!(expected,tree);
|
||||
@ -789,9 +839,11 @@ mod test {
|
||||
|
||||
// Check the other fields:
|
||||
clear_expression_ids(&mut tree.root);
|
||||
let crumb = AmbiguousCrumb{index:0, field:AmbiguousSegmentCrumb::Body};
|
||||
let head_crumb = AmbiguousCrumb{index:0, field:AmbiguousSegmentCrumb::Head};
|
||||
let body_crumb = AmbiguousCrumb{index:0, field:AmbiguousSegmentCrumb::Body};
|
||||
let expected = TreeBuilder::new(2)
|
||||
.add_leaf(1,1,node::Kind::argument(),crumb)
|
||||
.add_leaf(0,1,node::Kind::Token,head_crumb)
|
||||
.add_leaf(1,1,node::Kind::argument(),body_crumb)
|
||||
.build();
|
||||
|
||||
assert_eq!(expected,tree);
|
||||
@ -903,4 +955,14 @@ mod test {
|
||||
clear_parameter_infos(&mut tree.root);
|
||||
assert_eq!(tree,expected);
|
||||
}
|
||||
|
||||
fn segment_body_crumbs(index:usize, pattern_crumb:&Vec<PatternMatchCrumb>) -> ast::crumbs::MatchCrumb {
|
||||
let val = ast::crumbs::SegmentMatchCrumb::Body {val:pattern_crumb.clone()};
|
||||
ast::crumbs::MatchCrumb::Segs {val,index}
|
||||
}
|
||||
|
||||
fn segment_head_crumbs(index:usize) -> ast::crumbs::MatchCrumb {
|
||||
let val = ast::crumbs::SegmentMatchCrumb::Head;
|
||||
ast::crumbs::MatchCrumb::Segs {val,index}
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ pub enum Kind {
|
||||
This(This),
|
||||
/// A node being a normal (not target) parameter of parent Infix, Section or Prefix.
|
||||
Argument(Argument),
|
||||
/// A node being a unmodifiable token in macro.
|
||||
Token,
|
||||
/// A node being a placeholder for inserting new child to Prefix or Operator chain. It should
|
||||
/// not have children, but can be assigned with a span representing the number of spaces between
|
||||
/// AST tokens. For example, given expression `foo bar`, the span assigned to the
|
||||
|
Loading…
Reference in New Issue
Block a user