From 33f89522f6c31d8364a39f8b42cf17ead3133491 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 11 Sep 2019 12:16:05 -0700 Subject: [PATCH] Allow lisp-style comments in tree queries --- cli/src/tests/query_test.rs | 93 ++++++++++++++++++++++++------------- lib/src/query.c | 13 +++++- 2 files changed, 73 insertions(+), 33 deletions(-) diff --git a/cli/src/tests/query_test.rs b/cli/src/tests/query_test.rs index cfa6a2ba..5bf781b4 100644 --- a/cli/src/tests/query_test.rs +++ b/cli/src/tests/query_test.rs @@ -62,38 +62,6 @@ fn test_query_errors_on_invalid_symbols() { }); } -#[test] -fn test_query_capture_names() { - allocations::record(|| { - let language = get_language("javascript"); - let query = Query::new( - language, - r#" - (if_statement - condition: (binary_expression - left: * @left-operand - operator: "||" - right: * @right-operand) - consequence: (statement_block) @body) - - (while_statement - condition:* @loop-condition) - "#, - ) - .unwrap(); - - assert_eq!( - query.capture_names(), - &[ - "left-operand".to_string(), - "right-operand".to_string(), - "body".to_string(), - "loop-condition".to_string(), - ] - ); - }); -} - #[test] fn test_query_exec_with_simple_pattern() { allocations::record(|| { @@ -302,6 +270,67 @@ fn test_query_exec_too_many_match_permutations_to_track() { }); } +#[test] +fn test_query_capture_names() { + allocations::record(|| { + let language = get_language("javascript"); + let query = Query::new( + language, + r#" + (if_statement + condition: (binary_expression + left: * @left-operand + operator: "||" + right: * @right-operand) + consequence: (statement_block) @body) + + (while_statement + condition:* @loop-condition) + "#, + ) + .unwrap(); + + assert_eq!( + query.capture_names(), + &[ + "left-operand".to_string(), + "right-operand".to_string(), + "body".to_string(), + "loop-condition".to_string(), + ] + ); + }); +} + +#[test] +fn test_query_comments() { + allocations::record(|| { + let language = get_language("javascript"); + let query = Query::new( + language, + " + ; this is my first comment + ; i have two comments here + (function_declaration + ; there is also a comment here + ; and here + name: (identifier) @fn-name)", + ) + .unwrap(); + + let source = "function one() { }"; + let mut parser = Parser::new(); + parser.set_language(language).unwrap(); + let tree = parser.parse(source, None).unwrap(); + let context = query.context(); + let matches = context.exec(tree.root_node()); + assert_eq!( + collect_matches(matches, &query, source), + &[(0, vec![("fn-name", "one")]),], + ); + }); +} + fn collect_matches<'a>( matches: impl Iterator>, query: &'a Query, diff --git a/lib/src/query.c b/lib/src/query.c index 9325424b..fe8d2eec 100644 --- a/lib/src/query.c +++ b/lib/src/query.c @@ -147,7 +147,18 @@ static Stream stream_new(const char *string, uint32_t length) { } static void stream_skip_whitespace(Stream *stream) { - while (iswspace(stream->next)) stream_advance(stream); + for (;;) { + if (iswspace(stream->next)) { + stream_advance(stream); + } else if (stream->next == ';') { + stream_advance(stream); + while (stream->next && stream->next != '\n') { + if (!stream_advance(stream)) break; + } + } else { + break; + } + } } static bool stream_is_ident_start(Stream *stream) {