mirror of
https://github.com/github/codeql.git
synced 2026-05-14 19:29:28 +02:00
Yeast: Fix remaining review issues (#8-#10)
#8: Reject * after non-capture template groups with a compile error. Previously (foo (bar)*) silently dropped the *, behaving like (bar). #9: Verify inner token streams are exhausted after parsing query nodes. Unconsumed tokens inside a parenthesized group now produce a compile error. Fixed a test using the old redundant (pattern)* syntax inside a field*: group. #10: Use ast.get_root() instead of hardcoded 0 for the root node id in apply_rules calls. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -46,7 +46,11 @@ fn parse_query_atom(tokens: &mut Tokens) -> Result<TokenStream> {
|
||||
Some(TokenTree::Group(g)) if g.delimiter() == Delimiter::Parenthesis => {
|
||||
let group = expect_group(tokens, Delimiter::Parenthesis)?;
|
||||
let mut inner = group.stream().into_iter().peekable();
|
||||
parse_query_node_inner(&mut inner)
|
||||
let result = parse_query_node_inner(&mut inner)?;
|
||||
if let Some(tok) = inner.next() {
|
||||
return Err(syn::Error::new_spanned(tok, "unexpected token in query node"));
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
Some(tok) => Err(syn::Error::new_spanned(
|
||||
tok.clone(),
|
||||
@@ -348,8 +352,10 @@ fn parse_direct_node_inner(tokens: &mut Tokens, ctx: &Ident) -> Result<TokenStre
|
||||
__children.extend(#ctx.capture_all(#name_str));
|
||||
});
|
||||
} else {
|
||||
let node = parse_direct_node_inner(&mut inner, ctx)?;
|
||||
child_stmts.push(quote! { __children.push(#node); });
|
||||
return Err(syn::Error::new(
|
||||
Span::call_site(),
|
||||
"* after a non-capture group is not supported in tree templates; use (@name)* to splice a repeated capture",
|
||||
));
|
||||
}
|
||||
has_children = true;
|
||||
continue;
|
||||
|
||||
@@ -610,7 +610,8 @@ impl Runner {
|
||||
pub fn run_from_tree(&self, tree: &tree_sitter::Tree) -> Result<Ast, String> {
|
||||
let fresh = tree_builder::FreshScope::new();
|
||||
let mut ast = Ast::from_tree(self.language.clone(), tree);
|
||||
let res = apply_rules(&self.rules, &mut ast, 0, &fresh)?;
|
||||
let root = ast.get_root();
|
||||
let res = apply_rules(&self.rules, &mut ast, root, &fresh)?;
|
||||
if res.len() != 1 {
|
||||
return Err(format!("Expected exactly one result node, got {}", res.len()));
|
||||
}
|
||||
@@ -626,7 +627,8 @@ impl Runner {
|
||||
let tree = parser.parse(input, None)
|
||||
.ok_or_else(|| "Failed to parse input".to_string())?;
|
||||
let mut ast = Ast::from_tree(self.language.clone(), &tree);
|
||||
let res = apply_rules(&self.rules, &mut ast, 0, &fresh)?;
|
||||
let root = ast.get_root();
|
||||
let res = apply_rules(&self.rules, &mut ast, root, &fresh)?;
|
||||
if res.len() != 1 {
|
||||
return Err(format!("Expected exactly one result node, got {}", res.len()));
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ mod tests {
|
||||
let query9: QueryNode = yeast::query!(
|
||||
(assignment
|
||||
left: (element_reference
|
||||
object*: ((_) @obj)*
|
||||
object*: ((_) @obj)
|
||||
(_) @index
|
||||
)
|
||||
right: (_) @rhs
|
||||
|
||||
Reference in New Issue
Block a user