From da16cb14592bd6e3e6218cefc043da67e8f2c63f Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 27 Nov 2023 15:50:08 -0800 Subject: [PATCH] Introduce language ref-count management C APIs, remove Copy impl for Language in Rust --- cli/benches/benchmark.rs | 4 +- cli/loader/src/lib.rs | 2 +- cli/src/main.rs | 16 +- cli/src/parse.rs | 2 +- cli/src/query.rs | 6 +- cli/src/query_testing.rs | 2 +- cli/src/tags.rs | 2 +- cli/src/test.rs | 2 +- cli/src/test_highlight.rs | 7 +- cli/src/test_tags.rs | 3 +- cli/src/tests/async_context_test.rs | 8 +- cli/src/tests/corpus_test.rs | 8 +- cli/src/tests/github_issue_test.rs | 6 +- cli/src/tests/helpers/query_helpers.rs | 4 +- cli/src/tests/language_test.rs | 6 +- cli/src/tests/node_test.rs | 30 +- cli/src/tests/parser_test.rs | 72 ++--- cli/src/tests/pathological_test.rs | 2 +- cli/src/tests/query_test.rs | 417 +++++++++++++------------ cli/src/tests/text_provider_test.rs | 6 +- cli/src/tests/tree_test.rs | 16 +- highlight/src/lib.rs | 6 +- lib/binding_rust/bindings.rs | 8 + lib/binding_rust/lib.rs | 18 +- lib/include/tree_sitter/api.h | 11 + lib/src/language.c | 9 + tags/src/lib.rs | 4 +- 27 files changed, 363 insertions(+), 314 deletions(-) diff --git a/cli/benches/benchmark.rs b/cli/benches/benchmark.rs index ae82081a..51246f03 100644 --- a/cli/benches/benchmark.rs +++ b/cli/benches/benchmark.rs @@ -92,7 +92,7 @@ fn main() { eprintln!("\nLanguage: {}", language_name); let language = get_language(language_path); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); eprintln!(" Constructing Queries"); for path in query_paths { @@ -103,7 +103,7 @@ fn main() { } parse(&path, max_path_length, |source| { - Query::new(language, str::from_utf8(source).unwrap()) + Query::new(&language, str::from_utf8(source).unwrap()) .with_context(|| format!("Query file path: {path:?}")) .expect("Failed to parse query"); }); diff --git a/cli/loader/src/lib.rs b/cli/loader/src/lib.rs index 9586c984..1a789b1b 100644 --- a/cli/loader/src/lib.rs +++ b/cli/loader/src/lib.rs @@ -324,7 +324,7 @@ impl Loader { let src_path = path.join("src"); self.load_language_at_path(&src_path, &src_path) }) - .map(|l| *l) + .cloned() } pub fn load_language_at_path(&self, src_path: &Path, header_path: &Path) -> Result { diff --git a/cli/src/main.rs b/cli/src/main.rs index d6b143d5..4f60c3d2 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -414,7 +414,7 @@ fn run() -> Result<()> { let language = languages .first() .ok_or_else(|| anyhow!("No language found"))?; - parser.set_language(*language)?; + parser.set_language(&language)?; let test_dir = current_dir.join("test"); @@ -435,7 +435,7 @@ fn run() -> Result<()> { } // Check that all of the queries are valid. - test::check_queries_at_path(*language, ¤t_dir.join("queries"))?; + test::check_queries_at_path(language.clone(), ¤t_dir.join("queries"))?; // Run the syntax highlighting tests. let test_highlight_dir = test_dir.join("highlight"); @@ -527,11 +527,11 @@ fn run() -> Result<()> { let language = loader.select_language(path, ¤t_dir, matches.value_of("scope"))?; parser - .set_language(language) + .set_language(&language) .context("incompatible language")?; let opts = ParseFileOptions { - language, + language: language.clone(), path, edits: &edits, max_path_length, @@ -636,10 +636,10 @@ fn run() -> Result<()> { let cancellation_flag = util::cancel_on_signal(); - let mut lang = None; + let mut language = None; if let Some(scope) = matches.value_of("scope") { - lang = loader.language_configuration_for_scope(scope)?; - if lang.is_none() { + language = loader.language_configuration_for_scope(scope)?; + if language.is_none() { return Err(anyhow!("Unknown scope '{}'", scope)); } } @@ -655,7 +655,7 @@ fn run() -> Result<()> { for path in paths { let path = Path::new(&path); - let (language, language_config) = match lang { + let (language, language_config) = match language.clone() { Some(v) => v, None => match loader.language_configuration_for_file_name(path)? { Some(v) => v, diff --git a/cli/src/parse.rs b/cli/src/parse.rs index 14c4499d..d0ac687d 100644 --- a/cli/src/parse.rs +++ b/cli/src/parse.rs @@ -54,7 +54,7 @@ pub struct ParseFileOptions<'a> { pub fn parse_file_at_path(parser: &mut Parser, opts: ParseFileOptions) -> Result { let mut _log_session = None; - parser.set_language(opts.language)?; + parser.set_language(&opts.language)?; let mut source_code = fs::read(opts.path) .with_context(|| format!("Error reading source file {:?}", opts.path))?; diff --git a/cli/src/query.rs b/cli/src/query.rs index fc24cb05..20dc3cb2 100644 --- a/cli/src/query.rs +++ b/cli/src/query.rs @@ -25,7 +25,7 @@ pub fn query_files_at_paths( let query_source = fs::read_to_string(query_path) .with_context(|| format!("Error reading query file {:?}", query_path))?; - let query = Query::new(language, &query_source).with_context(|| "Query compilation failed")?; + let query = Query::new(&language, &query_source).with_context(|| "Query compilation failed")?; let mut query_cursor = QueryCursor::new(); if let Some(range) = byte_range { @@ -36,7 +36,7 @@ pub fn query_files_at_paths( } let mut parser = Parser::new(); - parser.set_language(language)?; + parser.set_language(&language)?; for path in paths { let mut results = Vec::new(); @@ -115,7 +115,7 @@ pub fn query_files_at_paths( )?; } if should_test { - query_testing::assert_expected_captures(results, path, &mut parser, language)? + query_testing::assert_expected_captures(results, path, &mut parser, language.clone())? } if print_time { writeln!(&mut stdout, "{:?}", start.elapsed())?; diff --git a/cli/src/query_testing.rs b/cli/src/query_testing.rs index 1f88d619..52764b62 100644 --- a/cli/src/query_testing.rs +++ b/cli/src/query_testing.rs @@ -45,7 +45,7 @@ pub fn parse_position_comments( // Parse the code. parser.set_included_ranges(&[]).unwrap(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); // Walk the tree, finding comment nodes that contain assertions. diff --git a/cli/src/tags.rs b/cli/src/tags.rs index f9f788ab..d3a02ceb 100644 --- a/cli/src/tags.rs +++ b/cli/src/tags.rs @@ -29,7 +29,7 @@ pub fn generate_tags( for path in paths { let path = Path::new(&path); - let (language, language_config) = match lang { + let (language, language_config) = match lang.clone() { Some(v) => v, None => match loader.language_configuration_for_file_name(path)? { Some(v) => v, diff --git a/cli/src/test.rs b/cli/src/test.rs index 2a452b73..f50e7200 100644 --- a/cli/src/test.rs +++ b/cli/src/test.rs @@ -141,7 +141,7 @@ pub fn check_queries_at_path(language: Language, path: &Path) -> Result<()> { let filepath = entry.file_name().to_str().unwrap_or(""); let content = fs::read_to_string(entry.path()) .with_context(|| format!("Error reading query file {:?}", filepath))?; - Query::new(language, &content) + Query::new(&language, &content) .with_context(|| format!("Error in query file {:?}", filepath))?; } } diff --git a/cli/src/test_highlight.rs b/cli/src/test_highlight.rs index 7e1a2927..bd70f8ca 100644 --- a/cli/src/test_highlight.rs +++ b/cli/src/test_highlight.rs @@ -197,8 +197,11 @@ pub fn test_highlight( // Highlight the file, and parse out all of the highlighting assertions. let highlight_names = loader.highlight_names(); let highlights = get_highlight_positions(loader, highlighter, highlight_config, source)?; - let assertions = - parse_position_comments(highlighter.parser(), highlight_config.language, source)?; + let assertions = parse_position_comments( + highlighter.parser(), + highlight_config.language.clone(), + source, + )?; iterate_assertions(&assertions, &highlights, &highlight_names) } diff --git a/cli/src/test_tags.rs b/cli/src/test_tags.rs index 0bf13fe2..f7caf456 100644 --- a/cli/src/test_tags.rs +++ b/cli/src/test_tags.rs @@ -88,7 +88,8 @@ pub fn test_tag( source: &[u8], ) -> Result { let tags = get_tag_positions(tags_context, tags_config, source)?; - let assertions = parse_position_comments(tags_context.parser(), tags_config.language, source)?; + let assertions = + parse_position_comments(tags_context.parser(), tags_config.language.clone(), source)?; // Iterate through all of the assertions, checking against the actual tags. let mut i = 0; diff --git a/cli/src/tests/async_context_test.rs b/cli/src/tests/async_context_test.rs index 08226387..ccd68006 100644 --- a/cli/src/tests/async_context_test.rs +++ b/cli/src/tests/async_context_test.rs @@ -10,7 +10,7 @@ fn test_node_in_fut() { let (ret, pended) = tokio_like_spawn(async { let mut parser = Parser::new(); let language = get_language("bash"); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse("#", None).unwrap(); @@ -64,7 +64,7 @@ fn test_node_and_cursor_ref_in_fut() { let (_, pended) = tokio_like_spawn(async { let mut parser = Parser::new(); let language = get_language("bash"); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse("#", None).unwrap(); @@ -103,7 +103,7 @@ fn test_node_and_cursor_ref_in_fut_with_fut_fabrics() { let (_, pended) = tokio_like_spawn(async { let mut parser = Parser::new(); let language = get_language("bash"); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse("#", None).unwrap(); @@ -141,7 +141,7 @@ fn test_node_and_cursor_ref_in_fut_with_inner_spawns() { let (ret, pended) = tokio_like_spawn(async { let mut parser = Parser::new(); let language = get_language("bash"); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse("#", None).unwrap(); diff --git a/cli/src/tests/corpus_test.rs b/cli/src/tests/corpus_test.rs index 589b1839..70894f25 100644 --- a/cli/src/tests/corpus_test.rs +++ b/cli/src/tests/corpus_test.rs @@ -138,7 +138,7 @@ fn test_language_corpus(language_name: &str, start_seed: usize, skipped: Option< let passed = allocations::record(|| { let mut log_session = None; let mut parser = get_parser(&mut log_session, "log.html"); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); set_included_ranges(&mut parser, &test.input, test.template_delimiters); let tree = parser.parse(&test.input, None).unwrap(); @@ -164,7 +164,7 @@ fn test_language_corpus(language_name: &str, start_seed: usize, skipped: Option< } let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(&test.input, None).unwrap(); drop(parser); @@ -174,7 +174,7 @@ fn test_language_corpus(language_name: &str, start_seed: usize, skipped: Option< let mut rand = Rand::new(seed); let mut log_session = None; let mut parser = get_parser(&mut log_session, "log.html"); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let mut tree = tree.clone(); let mut input = test.input.clone(); @@ -356,7 +356,7 @@ fn test_feature_corpus_files() { let passed = allocations::record(|| { let mut log_session = None; let mut parser = get_parser(&mut log_session, "log.html"); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(&test.input, None).unwrap(); let mut actual_output = tree.root_node().to_sexp(); if !test.has_fields { diff --git a/cli/src/tests/github_issue_test.rs b/cli/src/tests/github_issue_test.rs index bfc135ca..d04dde8a 100644 --- a/cli/src/tests/github_issue_test.rs +++ b/cli/src/tests/github_issue_test.rs @@ -14,7 +14,7 @@ use tree_sitter::Query; #[test] fn issue_2162_out_of_bound() { let language = get_language("java"); - assert!(Query::new(language, "(package_declaration _ (_) @name _)").is_ok()); + assert!(Query::new(&language, "(package_declaration _ (_) @name _)").is_ok()); } #[test] @@ -32,9 +32,9 @@ fn issue_2107_first_child_group_anchor_had_no_effect() { ) ) "#}; - let query = Query::new(language, query).unwrap(); + let query = Query::new(&language, query).unwrap(); assert_query_matches( - language, + &language, &query, source_code, &[(0, vec![("constant", "int a")])], diff --git a/cli/src/tests/helpers/query_helpers.rs b/cli/src/tests/helpers/query_helpers.rs index 4d71dfd0..50aa41db 100644 --- a/cli/src/tests/helpers/query_helpers.rs +++ b/cli/src/tests/helpers/query_helpers.rs @@ -308,13 +308,13 @@ fn compare_depth_first(a: Node, b: Node) -> Ordering { } pub fn assert_query_matches( - language: Language, + language: &Language, query: &Query, source: &str, expected: &[(usize, Vec<(&str, &str)>)], ) { let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); let matches = cursor.matches(&query, tree.root_node(), source.as_bytes()); diff --git a/cli/src/tests/language_test.rs b/cli/src/tests/language_test.rs index 3519f9c5..1a69e491 100644 --- a/cli/src/tests/language_test.rs +++ b/cli/src/tests/language_test.rs @@ -5,7 +5,7 @@ use tree_sitter::Parser; fn test_lookahead_iterator() { let mut parser = Parser::new(); let language = get_language("rust"); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse("struct Stuff {}", None).unwrap(); @@ -34,7 +34,7 @@ fn test_lookahead_iterator() { lookahead.reset_state(next_state); assert!(lookahead.iter_names().eq(expected_symbols)); - lookahead.reset(language, next_state); + lookahead.reset(language.clone(), next_state); assert!(lookahead .map(|s| language.node_kind_for_id(s).unwrap()) .eq(expected_symbols)); @@ -44,7 +44,7 @@ fn test_lookahead_iterator() { fn test_lookahead_iterator_modifiable_only_by_mut() { let mut parser = Parser::new(); let language = get_language("rust"); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse("struct Stuff {}", None).unwrap(); diff --git a/cli/src/tests/node_test.rs b/cli/src/tests/node_test.rs index c4548d3e..b1d93429 100644 --- a/cli/src/tests/node_test.rs +++ b/cli/src/tests/node_test.rs @@ -202,7 +202,7 @@ fn test_node_children() { #[test] fn test_node_children_by_field_name() { let mut parser = Parser::new(); - parser.set_language(get_language("python")).unwrap(); + parser.set_language(&get_language("python")).unwrap(); let source = " if one: a() @@ -230,7 +230,7 @@ fn test_node_children_by_field_name() { #[test] fn test_node_parent_of_child_by_field_name() { let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); let tree = parser.parse("foo(a().b[0].c.d.e())", None).unwrap(); let call_node = tree .root_node() @@ -251,7 +251,7 @@ fn test_node_parent_of_child_by_field_name() { #[test] fn test_node_field_name_for_child() { let mut parser = Parser::new(); - parser.set_language(get_language("c")).unwrap(); + parser.set_language(&get_language("c")).unwrap(); let tree = parser.parse("int w = x + y;", None).unwrap(); let translation_unit_node = tree.root_node(); let declaration_node = translation_unit_node.named_child(0).unwrap(); @@ -278,7 +278,7 @@ fn test_node_field_name_for_child() { #[test] fn test_node_child_by_field_name_with_extra_hidden_children() { let mut parser = Parser::new(); - parser.set_language(get_language("python")).unwrap(); + parser.set_language(&get_language("python")).unwrap(); // In the Python grammar, some fields are applied to `suite` nodes, // which consist of an invisible `indent` token followed by a block. @@ -373,7 +373,7 @@ fn test_node_named_child_with_aliases_and_extras() { let mut parser = Parser::new(); parser - .set_language(get_test_language(&parser_name, &parser_code, None)) + .set_language(&get_test_language(&parser_name, &parser_code, None)) .unwrap(); let tree = parser.parse("b ... b ... c", None).unwrap(); @@ -411,7 +411,7 @@ fn test_node_descendant_count() { fn test_descendant_count_single_node_tree() { let mut parser = Parser::new(); parser - .set_language(get_language("embedded-template")) + .set_language(&get_language("embedded-template")) .unwrap(); let tree = parser.parse("hello", None).unwrap(); @@ -576,7 +576,7 @@ fn test_node_edit() { #[test] fn test_root_node_with_offset() { let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); let tree = parser.parse(" if (a) b", None).unwrap(); let node = tree.root_node_with_offset(6, Point::new(2, 2)); @@ -604,7 +604,7 @@ fn test_root_node_with_offset() { #[test] fn test_node_is_extra() { let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); let tree = parser.parse("foo(/* hi */);", None).unwrap(); let root_node = tree.root_node(); @@ -619,7 +619,7 @@ fn test_node_is_extra() { #[test] fn test_node_sexp() { let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); let tree = parser.parse("if (a) b", None).unwrap(); let root_node = tree.root_node(); let if_node = root_node.descendant_for_byte_range(0, 0).unwrap(); @@ -708,7 +708,7 @@ fn test_node_field_names() { let mut parser = Parser::new(); let language = get_test_language(&parser_name, &parser_code, None); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser .parse("child-0 child-1 child-2 child-3 child-4", None) @@ -778,7 +778,7 @@ fn test_node_field_calls_in_language_without_fields() { let mut parser = Parser::new(); let language = get_test_language(&parser_name, &parser_code, None); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse("b c d", None).unwrap(); @@ -807,7 +807,7 @@ fn test_node_is_named_but_aliased_as_anonymous() { let mut parser = Parser::new(); let language = get_test_language(&parser_name, &parser_code, None); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse("B C B", None).unwrap(); @@ -826,7 +826,7 @@ fn test_node_is_named_but_aliased_as_anonymous() { #[test] fn test_node_numeric_symbols_respect_simple_aliases() { let mut parser = Parser::new(); - parser.set_language(get_language("python")).unwrap(); + parser.set_language(&get_language("python")).unwrap(); // Example 1: // Python argument lists can contain "splat" arguments, which are not allowed within @@ -857,7 +857,7 @@ fn test_node_numeric_symbols_respect_simple_aliases() { // Ruby handles the unary (negative) and binary (minus) `-` operators using two different // tokens. One or more of these is an external token that's aliased as `-`. Their numeric // kind ids should match. - parser.set_language(get_language("ruby")).unwrap(); + parser.set_language(&get_language("ruby")).unwrap(); let tree = parser.parse("-a - b", None).unwrap(); let root = tree.root_node(); assert_eq!( @@ -903,6 +903,6 @@ fn get_all_nodes(tree: &Tree) -> Vec { fn parse_json_example() -> Tree { let mut parser = Parser::new(); - parser.set_language(get_language("json")).unwrap(); + parser.set_language(&get_language("json")).unwrap(); parser.parse(JSON_EXAMPLE, None).unwrap() } diff --git a/cli/src/tests/parser_test.rs b/cli/src/tests/parser_test.rs index 8fb12357..a223a453 100644 --- a/cli/src/tests/parser_test.rs +++ b/cli/src/tests/parser_test.rs @@ -20,7 +20,7 @@ use tree_sitter_proc_macro::retry; #[test] fn test_parsing_simple_string() { let mut parser = Parser::new(); - parser.set_language(get_language("rust")).unwrap(); + parser.set_language(&get_language("rust")).unwrap(); let tree = parser .parse( @@ -51,7 +51,7 @@ fn test_parsing_simple_string() { #[test] fn test_parsing_with_logging() { let mut parser = Parser::new(); - parser.set_language(get_language("rust")).unwrap(); + parser.set_language(&get_language("rust")).unwrap(); let mut messages = Vec::new(); parser.set_logger(Some(Box::new(|log_type, message| { @@ -92,7 +92,7 @@ fn test_parsing_with_debug_graph_enabled() { let has_zero_indexed_row = |s: &str| s.contains("position: 0,"); let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); let mut debug_graph_file = tempfile::tempfile().unwrap(); parser.print_dot_graphs(&debug_graph_file); @@ -114,7 +114,7 @@ fn test_parsing_with_debug_graph_enabled() { #[test] fn test_parsing_with_custom_utf8_input() { let mut parser = Parser::new(); - parser.set_language(get_language("rust")).unwrap(); + parser.set_language(&get_language("rust")).unwrap(); let lines = &["pub fn foo() {", " 1", "}"]; @@ -157,7 +157,7 @@ fn test_parsing_with_custom_utf8_input() { #[test] fn test_parsing_with_custom_utf16_input() { let mut parser = Parser::new(); - parser.set_language(get_language("rust")).unwrap(); + parser.set_language(&get_language("rust")).unwrap(); let lines: Vec> = ["pub fn foo() {", " 1", "}"] .iter() @@ -196,7 +196,7 @@ fn test_parsing_with_custom_utf16_input() { #[test] fn test_parsing_with_callback_returning_owned_strings() { let mut parser = Parser::new(); - parser.set_language(get_language("rust")).unwrap(); + parser.set_language(&get_language("rust")).unwrap(); let text = b"pub fn foo() { 1 }"; @@ -217,7 +217,7 @@ fn test_parsing_with_callback_returning_owned_strings() { #[test] fn test_parsing_text_with_byte_order_mark() { let mut parser = Parser::new(); - parser.set_language(get_language("rust")).unwrap(); + parser.set_language(&get_language("rust")).unwrap(); // Parse UTF16 text with a BOM let tree = parser @@ -276,7 +276,7 @@ fn test_parsing_text_with_byte_order_mark() { #[test] fn test_parsing_invalid_chars_at_eof() { let mut parser = Parser::new(); - parser.set_language(get_language("json")).unwrap(); + parser.set_language(&get_language("json")).unwrap(); let tree = parser.parse(b"\xdf", None).unwrap(); assert_eq!( tree.root_node().to_sexp(), @@ -287,7 +287,7 @@ fn test_parsing_invalid_chars_at_eof() { #[test] fn test_parsing_unexpected_null_characters_within_source() { let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); let tree = parser.parse(b"var \0 something;", None).unwrap(); assert_eq!( tree.root_node().to_sexp(), @@ -298,7 +298,7 @@ fn test_parsing_unexpected_null_characters_within_source() { #[test] fn test_parsing_ends_when_input_callback_returns_empty() { let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); let mut i = 0; let source = b"abcdefghijklmnoqrs"; let tree = parser @@ -322,7 +322,7 @@ fn test_parsing_ends_when_input_callback_returns_empty() { #[test] fn test_parsing_after_editing_beginning_of_code() { let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); let mut code = b"123 + 456 * (10 + x);".to_vec(); let mut tree = parser.parse(&code, None).unwrap(); @@ -370,7 +370,7 @@ fn test_parsing_after_editing_beginning_of_code() { #[test] fn test_parsing_after_editing_end_of_code() { let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); let mut code = b"x * (100 + abc);".to_vec(); let mut tree = parser.parse(&code, None).unwrap(); @@ -418,7 +418,7 @@ fn test_parsing_after_editing_end_of_code() { #[test] fn test_parsing_empty_file_with_reused_tree() { let mut parser = Parser::new(); - parser.set_language(get_language("rust")).unwrap(); + parser.set_language(&get_language("rust")).unwrap(); let tree = parser.parse("", None); parser.parse("", tree.as_ref()); @@ -437,7 +437,7 @@ fn test_parsing_after_editing_tree_that_depends_on_column_values() { let mut parser = Parser::new(); parser - .set_language(get_test_language(&grammar_name, &parser_code, Some(&dir))) + .set_language(&get_test_language(&grammar_name, &parser_code, Some(&dir))) .unwrap(); let mut code = b" @@ -507,7 +507,7 @@ h + i #[test] fn test_parsing_after_detecting_error_in_the_middle_of_a_string_token() { let mut parser = Parser::new(); - parser.set_language(get_language("python")).unwrap(); + parser.set_language(&get_language("python")).unwrap(); let mut source = b"a = b, 'c, d'".to_vec(); let tree = parser.parse(&source, None).unwrap(); @@ -551,7 +551,7 @@ fn test_parsing_on_multiple_threads() { let this_file_source = include_str!("parser_test.rs"); let mut parser = Parser::new(); - parser.set_language(get_language("rust")).unwrap(); + parser.set_language(&get_language("rust")).unwrap(); let tree = parser.parse(this_file_source, None).unwrap(); let mut parse_threads = Vec::new(); @@ -579,7 +579,7 @@ fn test_parsing_on_multiple_threads() { // Reparse using the old tree as a starting point. let mut parser = Parser::new(); - parser.set_language(get_language("rust")).unwrap(); + parser.set_language(&get_language("rust")).unwrap(); parser.parse(&prepended_source, Some(&tree_clone)).unwrap() })); } @@ -600,7 +600,7 @@ fn test_parsing_cancelled_by_another_thread() { let cancellation_flag = std::sync::Arc::new(AtomicUsize::new(0)); let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); unsafe { parser.set_cancellation_flag(Some(&cancellation_flag)) }; // Long input - parsing succeeds @@ -649,7 +649,7 @@ fn test_parsing_cancelled_by_another_thread() { #[retry(10)] fn test_parsing_with_a_timeout() { let mut parser = Parser::new(); - parser.set_language(get_language("json")).unwrap(); + parser.set_language(&get_language("json")).unwrap(); // Parse an infinitely-long array, but pause after 1ms of processing. parser.set_timeout_micros(1000); @@ -711,7 +711,7 @@ fn test_parsing_with_a_timeout() { #[retry(10)] fn test_parsing_with_a_timeout_and_a_reset() { let mut parser = Parser::new(); - parser.set_language(get_language("json")).unwrap(); + parser.set_language(&get_language("json")).unwrap(); parser.set_timeout_micros(5); let tree = parser.parse( @@ -768,7 +768,7 @@ fn test_parsing_with_a_timeout_and_a_reset() { fn test_parsing_with_a_timeout_and_implicit_reset() { allocations::record(|| { let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); parser.set_timeout_micros(5); let tree = parser.parse( @@ -779,7 +779,7 @@ fn test_parsing_with_a_timeout_and_implicit_reset() { // Changing the parser's language implicitly resets, discarding // the previous partial parse. - parser.set_language(get_language("json")).unwrap(); + parser.set_language(&get_language("json")).unwrap(); parser.set_timeout_micros(0); let tree = parser.parse( "[null, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]", @@ -802,7 +802,7 @@ fn test_parsing_with_a_timeout_and_implicit_reset() { fn test_parsing_with_timeout_and_no_completion() { allocations::record(|| { let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); parser.set_timeout_micros(5); let tree = parser.parse( @@ -822,7 +822,7 @@ fn test_parsing_with_one_included_range() { let source_code = "hi"; let mut parser = Parser::new(); - parser.set_language(get_language("html")).unwrap(); + parser.set_language(&get_language("html")).unwrap(); let html_tree = parser.parse(source_code, None).unwrap(); let script_content_node = html_tree.root_node().child(1).unwrap().child(1).unwrap(); assert_eq!(script_content_node.kind(), "raw_text"); @@ -830,7 +830,7 @@ fn test_parsing_with_one_included_range() { parser .set_included_ranges(&[script_content_node.range()]) .unwrap(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); let js_tree = parser.parse(source_code, None).unwrap(); assert_eq!( @@ -853,7 +853,7 @@ fn test_parsing_with_multiple_included_ranges() { let source_code = "html `
Hello, ${name.toUpperCase()}, it's ${now()}.
`"; let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); let js_tree = parser.parse(source_code, None).unwrap(); let template_string_node = js_tree .root_node() @@ -869,7 +869,7 @@ fn test_parsing_with_multiple_included_ranges() { let interpolation_node2 = template_string_node.child(2).unwrap(); let close_quote_node = template_string_node.child(3).unwrap(); - parser.set_language(get_language("html")).unwrap(); + parser.set_language(&get_language("html")).unwrap(); let html_ranges = &[ Range { start_byte: open_quote_node.end_byte(), @@ -948,7 +948,7 @@ fn test_parsing_with_included_range_containing_mismatched_positions() { let source_code = "
test
{_ignore_this_part_}"; let mut parser = Parser::new(); - parser.set_language(get_language("html")).unwrap(); + parser.set_language(&get_language("html")).unwrap(); let end_byte = source_code.find("{_ignore_this_part_").unwrap(); @@ -1029,7 +1029,7 @@ fn test_parsing_utf16_code_with_errors_at_the_end_of_an_included_range() { let end_byte = 2 * source_code.find("").unwrap(); let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); parser .set_included_ranges(&[Range { start_byte, @@ -1051,7 +1051,7 @@ fn test_parsing_with_external_scanner_that_uses_included_range_boundaries() { let range2_end_byte = range2_start_byte + " d() ".len(); let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); parser .set_included_ranges(&[ Range { @@ -1095,7 +1095,7 @@ fn test_parsing_with_a_newly_excluded_range() { // Parse HTML including the template directive, which will cause an error let mut parser = Parser::new(); - parser.set_language(get_language("html")).unwrap(); + parser.set_language(&get_language("html")).unwrap(); let mut first_tree = parser .parse_with(&mut chunked_input(&source_code, 3), None) .unwrap(); @@ -1182,7 +1182,7 @@ fn test_parsing_with_a_newly_included_range() { // Parse only the first code directive as JavaScript let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); parser .set_included_ranges(&[simple_range(range1_start, range1_end)]) .unwrap(); @@ -1274,7 +1274,7 @@ fn test_parsing_with_included_ranges_and_missing_tokens() { let mut parser = Parser::new(); parser - .set_language(get_test_language(&parser_name, &parser_code, None)) + .set_language(&get_test_language(&parser_name, &parser_code, None)) .unwrap(); // There's a missing `a` token at the beginning of the code. It must be inserted @@ -1331,7 +1331,7 @@ fn test_grammars_that_can_hang_on_eof() { let mut parser = Parser::new(); parser - .set_language(get_test_language(&parser_name, &parser_code, None)) + .set_language(&get_test_language(&parser_name, &parser_code, None)) .unwrap(); parser.parse("\"", None).unwrap(); @@ -1356,7 +1356,7 @@ fn test_grammars_that_can_hang_on_eof() { .unwrap(); parser - .set_language(get_test_language(&parser_name, &parser_code, None)) + .set_language(&get_test_language(&parser_name, &parser_code, None)) .unwrap(); parser.parse("\"", None).unwrap(); @@ -1381,7 +1381,7 @@ fn test_grammars_that_can_hang_on_eof() { .unwrap(); parser - .set_language(get_test_language(&parser_name, &parser_code, None)) + .set_language(&get_test_language(&parser_name, &parser_code, None)) .unwrap(); parser.parse("\"", None).unwrap(); } diff --git a/cli/src/tests/pathological_test.rs b/cli/src/tests/pathological_test.rs index ec10884c..7e6dad16 100644 --- a/cli/src/tests/pathological_test.rs +++ b/cli/src/tests/pathological_test.rs @@ -8,7 +8,7 @@ fn test_pathological_example_1() { allocations::record(|| { let mut parser = Parser::new(); - parser.set_language(get_language(language)).unwrap(); + parser.set_language(&get_language(language)).unwrap(); parser.parse(source, None).unwrap(); }); } diff --git a/cli/src/tests/query_test.rs b/cli/src/tests/query_test.rs index 31d7e3f3..53dd5d26 100644 --- a/cli/src/tests/query_test.rs +++ b/cli/src/tests/query_test.rs @@ -27,16 +27,16 @@ fn test_query_errors_on_invalid_syntax() { allocations::record(|| { let language = get_language("javascript"); - assert!(Query::new(language, "(if_statement)").is_ok()); + assert!(Query::new(&language, "(if_statement)").is_ok()); assert!(Query::new( - language, + &language, "(if_statement condition:(parenthesized_expression (identifier)))" ) .is_ok()); // Mismatched parens assert_eq!( - Query::new(language, "(if_statement").unwrap_err().message, + Query::new(&language, "(if_statement").unwrap_err().message, [ "(if_statement", // " ^", @@ -44,7 +44,7 @@ fn test_query_errors_on_invalid_syntax() { .join("\n") ); assert_eq!( - Query::new(language, "; comment 1\n; comment 2\n (if_statement))") + Query::new(&language, "; comment 1\n; comment 2\n (if_statement))") .unwrap_err() .message, [ @@ -57,7 +57,7 @@ fn test_query_errors_on_invalid_syntax() { // Return an error at the *beginning* of a bare identifier not followed a colon. // If there's a colon but no pattern, return an error at the end of the colon. assert_eq!( - Query::new(language, "(if_statement identifier)") + Query::new(&language, "(if_statement identifier)") .unwrap_err() .message, [ @@ -67,7 +67,7 @@ fn test_query_errors_on_invalid_syntax() { .join("\n") ); assert_eq!( - Query::new(language, "(if_statement condition:)") + Query::new(&language, "(if_statement condition:)") .unwrap_err() .message, [ @@ -79,7 +79,7 @@ fn test_query_errors_on_invalid_syntax() { // Return an error at the beginning of an unterminated string. assert_eq!( - Query::new(language, r#"(identifier) "h "#) + Query::new(&language, r#"(identifier) "h "#) .unwrap_err() .message, [ @@ -91,7 +91,7 @@ fn test_query_errors_on_invalid_syntax() { // Empty tree pattern assert_eq!( - Query::new(language, r#"((identifier) ()"#) + Query::new(&language, r#"((identifier) ()"#) .unwrap_err() .message, [ @@ -103,7 +103,7 @@ fn test_query_errors_on_invalid_syntax() { // Empty alternation assert_eq!( - Query::new(language, r#"((identifier) [])"#) + Query::new(&language, r#"((identifier) [])"#) .unwrap_err() .message, [ @@ -115,7 +115,7 @@ fn test_query_errors_on_invalid_syntax() { // Unclosed sibling expression with predicate assert_eq!( - Query::new(language, r#"((identifier) (#a)"#) + Query::new(&language, r#"((identifier) (#a)"#) .unwrap_err() .message, [ @@ -127,7 +127,7 @@ fn test_query_errors_on_invalid_syntax() { // Unclosed predicate assert_eq!( - Query::new(language, r#"((identifier) @x (#eq? @x a"#) + Query::new(&language, r#"((identifier) @x (#eq? @x a"#) .unwrap_err() .message, [ @@ -139,7 +139,7 @@ fn test_query_errors_on_invalid_syntax() { // Need at least one child node for a child anchor assert_eq!( - Query::new(language, r#"(statement_block .)"#) + Query::new(&language, r#"(statement_block .)"#) .unwrap_err() .message, [ @@ -152,7 +152,7 @@ fn test_query_errors_on_invalid_syntax() { // Need a field name after a negated field operator assert_eq!( - Query::new(language, r#"(statement_block ! (if_statement))"#) + Query::new(&language, r#"(statement_block ! (if_statement))"#) .unwrap_err() .message, [ @@ -165,7 +165,7 @@ fn test_query_errors_on_invalid_syntax() { // Unclosed alternation within a tree // tree-sitter/tree-sitter/issues/968 assert_eq!( - Query::new(get_language("c"), r#"(parameter_list [ ")" @foo)"#) + Query::new(&get_language("c"), r#"(parameter_list [ ")" @foo)"#) .unwrap_err() .message, [ @@ -179,7 +179,7 @@ fn test_query_errors_on_invalid_syntax() { // tree-sitter/tree-sitter/issues/1436 assert_eq!( Query::new( - get_language("python"), + &get_language("python"), r#"[(unary_operator (_) @operand) (not_operator (_) @operand]"# ) .unwrap_err() @@ -199,7 +199,7 @@ fn test_query_errors_on_invalid_symbols() { let language = get_language("javascript"); assert_eq!( - Query::new(language, "(clas)").unwrap_err(), + Query::new(&language, "(clas)").unwrap_err(), QueryError { row: 0, offset: 1, @@ -209,7 +209,7 @@ fn test_query_errors_on_invalid_symbols() { } ); assert_eq!( - Query::new(language, "(if_statement (arrayyyyy))").unwrap_err(), + Query::new(&language, "(if_statement (arrayyyyy))").unwrap_err(), QueryError { row: 0, offset: 15, @@ -219,7 +219,7 @@ fn test_query_errors_on_invalid_symbols() { }, ); assert_eq!( - Query::new(language, "(if_statement condition: (non_existent3))").unwrap_err(), + Query::new(&language, "(if_statement condition: (non_existent3))").unwrap_err(), QueryError { row: 0, offset: 26, @@ -229,7 +229,7 @@ fn test_query_errors_on_invalid_symbols() { }, ); assert_eq!( - Query::new(language, "(if_statement condit: (identifier))").unwrap_err(), + Query::new(&language, "(if_statement condit: (identifier))").unwrap_err(), QueryError { row: 0, offset: 14, @@ -239,7 +239,7 @@ fn test_query_errors_on_invalid_symbols() { }, ); assert_eq!( - Query::new(language, "(if_statement conditioning: (identifier))").unwrap_err(), + Query::new(&language, "(if_statement conditioning: (identifier))").unwrap_err(), QueryError { row: 0, offset: 14, @@ -249,7 +249,7 @@ fn test_query_errors_on_invalid_symbols() { } ); assert_eq!( - Query::new(language, "(if_statement !alternativ)").unwrap_err(), + Query::new(&language, "(if_statement !alternativ)").unwrap_err(), QueryError { row: 0, offset: 15, @@ -259,7 +259,7 @@ fn test_query_errors_on_invalid_symbols() { } ); assert_eq!( - Query::new(language, "(if_statement !alternatives)").unwrap_err(), + Query::new(&language, "(if_statement !alternatives)").unwrap_err(), QueryError { row: 0, offset: 15, @@ -277,7 +277,7 @@ fn test_query_errors_on_invalid_predicates() { let language = get_language("javascript"); assert_eq!( - Query::new(language, "((identifier) @id (@id))").unwrap_err(), + Query::new(&language, "((identifier) @id (@id))").unwrap_err(), QueryError { kind: QueryErrorKind::Syntax, row: 0, @@ -291,7 +291,7 @@ fn test_query_errors_on_invalid_predicates() { } ); assert_eq!( - Query::new(language, "((identifier) @id (#eq? @id))").unwrap_err(), + Query::new(&language, "((identifier) @id (#eq? @id))").unwrap_err(), QueryError { kind: QueryErrorKind::Predicate, row: 0, @@ -302,7 +302,7 @@ fn test_query_errors_on_invalid_predicates() { } ); assert_eq!( - Query::new(language, "((identifier) @id (#eq? @id @ok))").unwrap_err(), + Query::new(&language, "((identifier) @id (#eq? @id @ok))").unwrap_err(), QueryError { kind: QueryErrorKind::Capture, row: 0, @@ -322,7 +322,7 @@ fn test_query_errors_on_impossible_patterns() { allocations::record(|| { assert_eq!( Query::new( - js_lang, + &js_lang, "(binary_expression left: (expression (identifier)) left: (expression (identifier)))" ), Err(QueryError { @@ -339,12 +339,12 @@ fn test_query_errors_on_impossible_patterns() { ); Query::new( - js_lang, + &js_lang, "(function_declaration name: (identifier) (statement_block))", ) .unwrap(); assert_eq!( - Query::new(js_lang, "(function_declaration name: (statement_block))"), + Query::new(&js_lang, "(function_declaration name: (statement_block))"), Err(QueryError { kind: QueryErrorKind::Structure, row: 0, @@ -358,9 +358,9 @@ fn test_query_errors_on_impossible_patterns() { }) ); - Query::new(rb_lang, "(call receiver:(call))").unwrap(); + Query::new(&rb_lang, "(call receiver:(call))").unwrap(); assert_eq!( - Query::new(rb_lang, "(call receiver:(binary))"), + Query::new(&rb_lang, "(call receiver:(binary))"), Err(QueryError { kind: QueryErrorKind::Structure, row: 0, @@ -375,7 +375,7 @@ fn test_query_errors_on_impossible_patterns() { ); Query::new( - js_lang, + &js_lang, "[ (function (identifier)) (function_declaration (identifier)) @@ -385,7 +385,7 @@ fn test_query_errors_on_impossible_patterns() { .unwrap(); assert_eq!( Query::new( - js_lang, + &js_lang, "[ (function (identifier)) (function_declaration (object)) @@ -406,7 +406,7 @@ fn test_query_errors_on_impossible_patterns() { ); assert_eq!( - Query::new(js_lang, "(identifier (identifier))",), + Query::new(&js_lang, "(identifier (identifier))",), Err(QueryError { kind: QueryErrorKind::Structure, row: 0, @@ -420,7 +420,7 @@ fn test_query_errors_on_impossible_patterns() { }) ); assert_eq!( - Query::new(js_lang, "(true (true))",), + Query::new(&js_lang, "(true (true))",), Err(QueryError { kind: QueryErrorKind::Structure, row: 0, @@ -435,14 +435,14 @@ fn test_query_errors_on_impossible_patterns() { ); Query::new( - js_lang, + &js_lang, "(if_statement condition: (parenthesized_expression (expression) @cond))", ) .unwrap(); assert_eq!( - Query::new(js_lang, "(if_statement condition: (expression))",), + Query::new(&js_lang, "(if_statement condition: (expression))"), Err(QueryError { kind: QueryErrorKind::Structure, row: 0, @@ -461,12 +461,12 @@ fn test_query_errors_on_impossible_patterns() { #[test] fn test_query_verifies_possible_patterns_with_aliased_parent_nodes() { allocations::record(|| { - let ruby = get_language("ruby"); + let language = get_language("ruby"); - Query::new(ruby, "(destructured_parameter (identifier))").unwrap(); + Query::new(&language, "(destructured_parameter (identifier))").unwrap(); assert_eq!( - Query::new(ruby, "(destructured_parameter (string))",), + Query::new(&language, "(destructured_parameter (string))",), Err(QueryError { kind: QueryErrorKind::Structure, row: 0, @@ -487,13 +487,13 @@ fn test_query_matches_with_simple_pattern() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, "(function_declaration name: (identifier) @fn-name)", ) .unwrap(); assert_query_matches( - language, + &language, &query, "function one() { two(); function three() {} }", &[ @@ -509,7 +509,7 @@ fn test_query_matches_with_multiple_on_same_root() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, "(class_declaration name: (identifier) @the-class-name (class_body @@ -519,7 +519,7 @@ fn test_query_matches_with_multiple_on_same_root() { .unwrap(); assert_query_matches( - language, + &language, &query, " class Person { @@ -555,7 +555,7 @@ fn test_query_matches_with_multiple_patterns_different_roots() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, " (function_declaration name:(identifier) @fn-def) (call_expression function:(identifier) @fn-ref) @@ -564,7 +564,7 @@ fn test_query_matches_with_multiple_patterns_different_roots() { .unwrap(); assert_query_matches( - language, + &language, &query, " function f1() { @@ -585,7 +585,7 @@ fn test_query_matches_with_multiple_patterns_same_root() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, " (pair key: (property_identifier) @method-def @@ -599,7 +599,7 @@ fn test_query_matches_with_multiple_patterns_same_root() { .unwrap(); assert_query_matches( - language, + &language, &query, " a = { @@ -620,7 +620,7 @@ fn test_query_matches_with_nesting_and_no_fields() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, " (array (array @@ -631,7 +631,7 @@ fn test_query_matches_with_nesting_and_no_fields() { .unwrap(); assert_query_matches( - language, + &language, &query, " [[a]]; @@ -655,10 +655,10 @@ fn test_query_matches_with_nesting_and_no_fields() { fn test_query_matches_with_many_results() { allocations::record(|| { let language = get_language("javascript"); - let query = Query::new(language, "(array (identifier) @element)").unwrap(); + let query = Query::new(&language, "(array (identifier) @element)").unwrap(); assert_query_matches( - language, + &language, &query, &"[hello];\n".repeat(50), &vec![(0, vec![("element", "hello")]); 50], @@ -671,7 +671,7 @@ fn test_query_matches_with_many_overlapping_results() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, r#" (call_expression function: (member_expression @@ -696,7 +696,7 @@ fn test_query_matches_with_many_overlapping_results() { source += &"\n .foo(bar(BAZ))".repeat(count); assert_query_matches( - language, + &language, &query, &source, &[ @@ -718,7 +718,7 @@ fn test_query_matches_capturing_error_nodes() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, " (ERROR (identifier) @the-error-identifier) @the-error ", @@ -726,7 +726,7 @@ fn test_query_matches_capturing_error_nodes() { .unwrap(); assert_query_matches( - language, + &language, &query, "function a(b,, c, d :e:) {}", &[(0, vec![("the-error", ":e:"), ("the-error-identifier", "e")])], @@ -739,7 +739,7 @@ fn test_query_matches_with_extra_children() { allocations::record(|| { let language = get_language("ruby"); let query = Query::new( - language, + &language, " (program(comment) @top_level_comment) (argument_list (heredoc_body) @heredoc_in_args) @@ -748,7 +748,7 @@ fn test_query_matches_with_extra_children() { .unwrap(); assert_query_matches( - language, + &language, &query, " # top-level @@ -782,7 +782,7 @@ fn test_query_matches_with_named_wildcard() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, " (return_statement (_) @the-return-value) (binary_expression operator: _ @the-operator) @@ -793,7 +793,7 @@ fn test_query_matches_with_named_wildcard() { let source = "return a + b - c;"; let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); let matches = cursor.matches(&query, tree.root_node(), source.as_bytes()); @@ -814,7 +814,7 @@ fn test_query_matches_with_wildcard_at_the_root() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, " (_ (comment) @doc @@ -826,14 +826,14 @@ fn test_query_matches_with_wildcard_at_the_root() { .unwrap(); assert_query_matches( - language, + &language, &query, "/* one */ var x; /* two */ function y() {} /* three */ class Z {}", &[(0, vec![("doc", "/* two */"), ("name", "y")])], ); let query = Query::new( - language, + &language, " (_ (string) @a) (_ (number) @b) @@ -844,7 +844,7 @@ fn test_query_matches_with_wildcard_at_the_root() { .unwrap(); assert_query_matches( - language, + &language, &query, "['hi', x(true), {y: false}]", &[ @@ -861,7 +861,7 @@ fn test_query_matches_with_wildcard_within_wildcard() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, " (_ (_) @child) @parent ", @@ -869,7 +869,7 @@ fn test_query_matches_with_wildcard_within_wildcard() { .unwrap(); assert_query_matches( - language, + &language, &query, "/* a */ b; c;", &[ @@ -896,7 +896,7 @@ fn test_query_matches_with_immediate_siblings() { // 2. Between two child nodes in a pattern, it specifies that there cannot be any // named siblings between those two child snodes. let query = Query::new( - language, + &language, " (dotted_name (identifier) @parent @@ -913,7 +913,7 @@ fn test_query_matches_with_immediate_siblings() { .unwrap(); assert_query_matches( - language, + &language, &query, "import a.b.c.d; return [w, [1, y], z]", &[ @@ -927,7 +927,7 @@ fn test_query_matches_with_immediate_siblings() { ); let query = Query::new( - language, + &language, " (block . (_) @first-stmt) (block (_) @stmt) @@ -937,7 +937,7 @@ fn test_query_matches_with_immediate_siblings() { .unwrap(); assert_query_matches( - language, + &language, &query, " if a: @@ -967,7 +967,7 @@ fn test_query_matches_with_last_named_child() { allocations::record(|| { let language = get_language("c"); let query = Query::new( - language, + &language, "(compound_statement (_) (_) @@ -976,7 +976,7 @@ fn test_query_matches_with_last_named_child() { ) .unwrap(); assert_query_matches( - language, + &language, &query, " void one() { a; b; c; } @@ -993,7 +993,7 @@ fn test_query_matches_with_negated_fields() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, " (import_specifier !alias @@ -1026,7 +1026,7 @@ fn test_query_matches_with_negated_fields() { ) .unwrap(); assert_query_matches( - language, + &language, &query, " import {a as b, c} from 'p1'; @@ -1057,9 +1057,9 @@ fn test_query_matches_with_negated_fields() { fn test_query_matches_with_field_at_root() { allocations::record(|| { let language = get_language("javascript"); - let query = Query::new(language, "name: (identifier) @name").unwrap(); + let query = Query::new(&language, "name: (identifier) @name").unwrap(); assert_query_matches( - language, + &language, &query, " a(); @@ -1077,7 +1077,7 @@ fn test_query_matches_with_repeated_leaf_nodes() { let language = get_language("javascript"); let query = Query::new( - language, + &language, " ( (comment)+ @doc @@ -1097,7 +1097,7 @@ fn test_query_matches_with_repeated_leaf_nodes() { .unwrap(); assert_query_matches( - language, + &language, &query, " // one @@ -1138,10 +1138,10 @@ fn test_query_matches_with_repeated_leaf_nodes() { fn test_query_matches_with_optional_nodes_inside_of_repetitions() { allocations::record(|| { let language = get_language("javascript"); - let query = Query::new(language, r#"(array (","? (number) @num)+)"#).unwrap(); + let query = Query::new(&language, r#"(array (","? (number) @num)+)"#).unwrap(); assert_query_matches( - language, + &language, &query, r#" var a = [1, 2, 3, 4] @@ -1159,7 +1159,7 @@ fn test_query_matches_with_top_level_repetitions() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, r#" (comment)+ @doc "#, @@ -1167,7 +1167,7 @@ fn test_query_matches_with_top_level_repetitions() { .unwrap(); assert_query_matches( - language, + &language, &query, r#" // a @@ -1190,10 +1190,10 @@ fn test_query_matches_with_top_level_repetitions() { fn test_query_matches_with_non_terminal_repetitions_within_root() { allocations::record(|| { let language = get_language("javascript"); - let query = Query::new(language, "(_ (expression_statement (identifier) @id)+)").unwrap(); + let query = Query::new(&language, "(_ (expression_statement (identifier) @id)+)").unwrap(); assert_query_matches( - language, + &language, &query, r#" function f() { @@ -1219,7 +1219,7 @@ fn test_query_matches_with_nested_repetitions() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, r#" (variable_declaration (","? (variable_declarator name: (identifier) @x))+)+ @@ -1228,7 +1228,7 @@ fn test_query_matches_with_nested_repetitions() { .unwrap(); assert_query_matches( - language, + &language, &query, r#" var a = b, c, d @@ -1256,7 +1256,7 @@ fn test_query_matches_with_multiple_repetition_patterns_that_intersect_other_pat // When this query sees a comment, it must keep track of several potential // matches: up to two for each pattern that begins with a comment. let query = Query::new( - language, + &language, r#" (call_expression function: (member_expression @@ -1283,7 +1283,7 @@ fn test_query_matches_with_multiple_repetition_patterns_that_intersect_other_pat ); assert_query_matches( - language, + &language, &query, &source, &vec![(7, vec![("comment", "// the comment")]); 64] @@ -1303,7 +1303,7 @@ fn test_query_matches_with_trailing_repetitions_of_last_child() { let language = get_language("javascript"); let query = Query::new( - language, + &language, " (unary_expression (primary_expression)+ @operand) ", @@ -1311,7 +1311,7 @@ fn test_query_matches_with_trailing_repetitions_of_last_child() { .unwrap(); assert_query_matches( - language, + &language, &query, " a = typeof (!b && ~c); @@ -1331,7 +1331,7 @@ fn test_query_matches_with_leading_zero_or_more_repeated_leaf_nodes() { let language = get_language("javascript"); let query = Query::new( - language, + &language, " ( (comment)* @doc @@ -1344,7 +1344,7 @@ fn test_query_matches_with_leading_zero_or_more_repeated_leaf_nodes() { .unwrap(); assert_query_matches( - language, + &language, &query, " function a() { @@ -1384,7 +1384,7 @@ fn test_query_matches_with_trailing_optional_nodes() { let language = get_language("javascript"); let query = Query::new( - language, + &language, " (class_declaration name: (identifier) @class @@ -1394,10 +1394,15 @@ fn test_query_matches_with_trailing_optional_nodes() { ) .unwrap(); - assert_query_matches(language, &query, "class A {}", &[(0, vec![("class", "A")])]); + assert_query_matches( + &language, + &query, + "class A {}", + &[(0, vec![("class", "A")])], + ); assert_query_matches( - language, + &language, &query, " class A {} @@ -1420,7 +1425,7 @@ fn test_query_matches_with_nested_optional_nodes() { // A function call, optionally containing a function call, which optionally contains a number let query = Query::new( - language, + &language, " (call_expression function: (identifier) @outer-fn @@ -1434,7 +1439,7 @@ fn test_query_matches_with_nested_optional_nodes() { .unwrap(); assert_query_matches( - language, + &language, &query, r#" a(b, c(), d(null, 1, 2)) @@ -1460,7 +1465,7 @@ fn test_query_matches_with_repeated_internal_nodes() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, " (_ (method_definition @@ -1471,7 +1476,7 @@ fn test_query_matches_with_repeated_internal_nodes() { .unwrap(); assert_query_matches( - language, + &language, &query, " class A { @@ -1490,7 +1495,7 @@ fn test_query_matches_with_simple_alternatives() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, " (pair key: [(property_identifier) (string)] @key @@ -1500,7 +1505,7 @@ fn test_query_matches_with_simple_alternatives() { .unwrap(); assert_query_matches( - language, + &language, &query, " a = { @@ -1529,7 +1534,7 @@ fn test_query_matches_with_alternatives_in_repetitions() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, r#" (array [(identifier) (string)] @el @@ -1544,7 +1549,7 @@ fn test_query_matches_with_alternatives_in_repetitions() { .unwrap(); assert_query_matches( - language, + &language, &query, " a = [b, 'c', d, 1, e, 'f', 'g', h]; @@ -1565,7 +1570,7 @@ fn test_query_matches_with_alternatives_at_root() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, r#" [ "if" @@ -1579,7 +1584,7 @@ fn test_query_matches_with_alternatives_at_root() { .unwrap(); assert_query_matches( - language, + &language, &query, " function a(b, c, d) { @@ -1606,7 +1611,7 @@ fn test_query_matches_with_alternatives_under_fields() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, r#" (assignment_expression left: [ @@ -1618,7 +1623,7 @@ fn test_query_matches_with_alternatives_under_fields() { .unwrap(); assert_query_matches( - language, + &language, &query, " a = b; @@ -1644,10 +1649,10 @@ fn test_query_matches_in_language_with_simple_aliases() { // HTML uses different tokens to track start tags names, end // tag names, script tag names, and style tag names. All of // these tokens are aliased to `tag_name`. - let query = Query::new(language, "(tag_name) @tag").unwrap(); + let query = Query::new(&language, "(tag_name) @tag").unwrap(); assert_query_matches( - language, + &language, &query, "
@@ -1674,7 +1679,7 @@ fn test_query_matches_with_different_tokens_with_the_same_string_value() { // and one with higher precedence for generics. let language = get_language("rust"); let query = Query::new( - language, + &language, r#" "<" @less ">" @greater @@ -1683,7 +1688,7 @@ fn test_query_matches_with_different_tokens_with_the_same_string_value() { .unwrap(); assert_query_matches( - language, + &language, &query, "const A: B = d < e || f > g;", &[ @@ -1701,7 +1706,7 @@ fn test_query_matches_with_too_many_permutations_to_track() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, " (array (identifier) @pre (identifier) @post) ", @@ -1713,7 +1718,7 @@ fn test_query_matches_with_too_many_permutations_to_track() { source.push_str("];"); let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(&source, None).unwrap(); let mut cursor = QueryCursor::new(); cursor.set_match_limit(32); @@ -1735,7 +1740,7 @@ fn test_query_sibling_patterns_dont_match_children_of_an_error() { allocations::record(|| { let language = get_language("rust"); let query = Query::new( - language, + &language, r#" ("{" @open "}" @close) @@ -1774,7 +1779,7 @@ fn test_query_sibling_patterns_dont_match_children_of_an_error() { "; let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); let matches = cursor.matches(&query, tree.root_node(), source.as_bytes()); @@ -1795,7 +1800,7 @@ fn test_query_matches_with_alternatives_and_too_many_permutations_to_track() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, " ( (comment) @doc @@ -1815,7 +1820,7 @@ fn test_query_matches_with_alternatives_and_too_many_permutations_to_track() { let source = "/* hi */ a.b(); ".repeat(50); let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(&source, None).unwrap(); let mut cursor = QueryCursor::new(); cursor.set_match_limit(32); @@ -1834,7 +1839,7 @@ fn test_repetitions_before_with_alternatives() { allocations::record(|| { let language = get_language("rust"); let query = Query::new( - language, + &language, r#" ( (line_comment)* @comment @@ -1851,7 +1856,7 @@ fn test_repetitions_before_with_alternatives() { .unwrap(); assert_query_matches( - language, + &language, &query, r#" // a @@ -1881,7 +1886,7 @@ fn test_query_matches_with_anonymous_tokens() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, r#" ";" @punctuation "&&" @operator @@ -1891,7 +1896,7 @@ fn test_query_matches_with_anonymous_tokens() { .unwrap(); assert_query_matches( - language, + &language, &query, r#"foo(a && "b");"#, &[ @@ -1909,7 +1914,7 @@ fn test_query_matches_with_supertypes() { allocations::record(|| { let language = get_language("python"); let query = Query::new( - language, + &language, r#" (argument_list (expression) @arg) @@ -1925,7 +1930,7 @@ fn test_query_matches_with_supertypes() { .unwrap(); assert_query_matches( - language, + &language, &query, " a = b.c( @@ -1950,12 +1955,12 @@ fn test_query_matches_with_supertypes() { fn test_query_matches_within_byte_range() { allocations::record(|| { let language = get_language("javascript"); - let query = Query::new(language, "(identifier) @element").unwrap(); + let query = Query::new(&language, "(identifier) @element").unwrap(); let source = "[a, b, c, d, e, f, g]"; let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); @@ -2005,7 +2010,7 @@ fn test_query_matches_within_byte_range() { fn test_query_matches_within_point_range() { allocations::record(|| { let language = get_language("javascript"); - let query = Query::new(language, "(identifier) @element").unwrap(); + let query = Query::new(&language, "(identifier) @element").unwrap(); let source = " [ @@ -2020,7 +2025,7 @@ fn test_query_matches_within_point_range() { .unindent(); let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(&source, None).unwrap(); let mut cursor = QueryCursor::new(); @@ -2071,7 +2076,7 @@ fn test_query_captures_within_byte_range() { allocations::record(|| { let language = get_language("c"); let query = Query::new( - language, + &language, " (call_expression function: (identifier) @function @@ -2085,7 +2090,7 @@ fn test_query_captures_within_byte_range() { let source = r#"DEFUN ("safe-length", Fsafe_length, Ssafe_length, 1, 1, 0)"#; let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); @@ -2177,7 +2182,7 @@ fn test_query_matches_with_unrooted_patterns_intersecting_byte_range() { allocations::record(|| { let language = get_language("rust"); let query = Query::new( - language, + &language, r#" ("{" @left "}" @right) ("<" @left ">" @right) @@ -2188,7 +2193,7 @@ fn test_query_matches_with_unrooted_patterns_intersecting_byte_range() { let source = "mod a { fn a(f: B) { g(f) } }"; let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); @@ -2231,7 +2236,7 @@ fn test_query_matches_with_wildcard_at_root_intersecting_byte_range() { allocations::record(|| { let language = get_language("python"); let query = Query::new( - language, + &language, " [ (_ body: (block)) @@ -2252,7 +2257,7 @@ fn test_query_matches_with_wildcard_at_root_intersecting_byte_range() { .trim(); let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); @@ -2293,7 +2298,7 @@ fn test_query_captures_within_byte_range_assigned_after_iterating() { allocations::record(|| { let language = get_language("rust"); let query = Query::new( - language, + &language, r#" (function_item name: (identifier) @fn_name) @@ -2326,7 +2331,7 @@ fn test_query_captures_within_byte_range_assigned_after_iterating() { "; let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); let mut captures = cursor.captures(&query, tree.root_node(), source.as_bytes()); @@ -2379,7 +2384,7 @@ fn test_query_matches_within_range_of_long_repetition() { allocations::record(|| { let language = get_language("rust"); let query = Query::new( - language, + &language, " (function_item name: (identifier) @fn-name) ", @@ -2406,7 +2411,7 @@ fn test_query_matches_within_range_of_long_repetition() { let mut parser = Parser::new(); let mut cursor = QueryCursor::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(&source, None).unwrap(); let matches = cursor @@ -2430,14 +2435,14 @@ fn test_query_matches_different_queries_same_cursor() { allocations::record(|| { let language = get_language("javascript"); let query1 = Query::new( - language, + &language, " (array (identifier) @id1) ", ) .unwrap(); let query2 = Query::new( - language, + &language, " (array (identifier) @id1) (pair (identifier) @id2) @@ -2445,7 +2450,7 @@ fn test_query_matches_different_queries_same_cursor() { ) .unwrap(); let query3 = Query::new( - language, + &language, " (array (identifier) @id1) (pair (identifier) @id2) @@ -2459,7 +2464,7 @@ fn test_query_matches_different_queries_same_cursor() { let mut parser = Parser::new(); let mut cursor = QueryCursor::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let matches = cursor.matches(&query1, tree.root_node(), source.as_bytes()); @@ -2491,7 +2496,7 @@ fn test_query_matches_with_multiple_captures_on_a_node() { allocations::record(|| { let language = get_language("javascript"); let mut query = Query::new( - language, + &language, "(function_declaration (identifier) @name1 @name2 @name3 (statement_block) @body1 @body2)", @@ -2502,7 +2507,7 @@ fn test_query_matches_with_multiple_captures_on_a_node() { let mut parser = Parser::new(); let mut cursor = QueryCursor::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let matches = cursor.matches(&query, tree.root_node(), source.as_bytes()); @@ -2544,7 +2549,7 @@ fn test_query_matches_with_captured_wildcard_at_root() { allocations::record(|| { let language = get_language("python"); let query = Query::new( - language, + &language, " ; captured wildcard at the root (_ [ @@ -2590,7 +2595,7 @@ fn test_query_matches_with_captured_wildcard_at_root() { let mut parser = Parser::new(); let mut cursor = QueryCursor::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let match_capture_names_and_rows = cursor @@ -2631,7 +2636,7 @@ fn test_query_matches_with_no_captures() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, r#" (identifier) (string) @s @@ -2640,7 +2645,7 @@ fn test_query_matches_with_no_captures() { .unwrap(); assert_query_matches( - language, + &language, &query, " a = 'hi'; @@ -2661,13 +2666,13 @@ fn test_query_matches_with_repeated_fields() { allocations::record(|| { let language = get_language("c"); let query = Query::new( - language, + &language, "(field_declaration declarator: (field_identifier) @field)", ) .unwrap(); assert_query_matches( - language, + &language, &query, " struct S { @@ -2688,7 +2693,7 @@ fn test_query_matches_with_deeply_nested_patterns_with_fields() { allocations::record(|| { let language = get_language("python"); let query = Query::new( - language, + &language, " (call function: (_) @func @@ -2715,7 +2720,7 @@ fn test_query_matches_with_deeply_nested_patterns_with_fields() { .unwrap(); assert_query_matches( - language, + &language, &query, " a(1).b(2).c(3).d(4).e(5).f(6).g(7).h(8) @@ -2783,7 +2788,7 @@ fn test_query_matches_with_indefinite_step_containing_no_captures() { // https://github.com/tree-sitter/tree-sitter/issues/937 let language = get_language("c"); let query = Query::new( - language, + &language, "(struct_specifier name: (type_identifier) @name body: (field_declaration_list @@ -2793,7 +2798,7 @@ fn test_query_matches_with_indefinite_step_containing_no_captures() { .unwrap(); assert_query_matches( - language, + &language, &query, " struct LacksUnionField { @@ -2826,7 +2831,7 @@ fn test_query_captures_basic() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, r#" (pair key: _ @method.def @@ -2856,7 +2861,7 @@ fn test_query_captures_basic() { "; let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); let matches = cursor.matches(&query, tree.root_node(), source.as_bytes()); @@ -2901,7 +2906,7 @@ fn test_query_captures_with_text_conditions() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, r#" ((identifier) @constant (#match? @constant "^[A-Z]{2,}$")) @@ -2939,7 +2944,7 @@ fn test_query_captures_with_text_conditions() { "; let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); @@ -2974,7 +2979,7 @@ fn test_query_captures_with_predicates() { let language = get_language("javascript"); let query = Query::new( - language, + &language, r#" ((call_expression (identifier) @foo) (#set! name something) @@ -3027,7 +3032,7 @@ fn test_query_captures_with_quoted_predicate_args() { // * escaped double quotes with \* // * literal backslashes with \\ let query = Query::new( - language, + &language, r#" ((call_expression (identifier) @foo) (#set! one "\"something\ngreat\"")) @@ -3069,7 +3074,7 @@ fn test_query_captures_with_duplicates() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, r#" (variable_declarator name: (identifier) @function @@ -3085,7 +3090,7 @@ fn test_query_captures_with_duplicates() { "; let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); @@ -3104,7 +3109,7 @@ fn test_query_captures_with_many_nested_results_without_fields() { // Search for key-value pairs whose values are anonymous functions. let query = Query::new( - language, + &language, r#" (pair key: _ @method-def @@ -3129,7 +3134,7 @@ fn test_query_captures_with_many_nested_results_without_fields() { source.push_str("}};\n"); let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(&source, None).unwrap(); let mut cursor = QueryCursor::new(); @@ -3167,7 +3172,7 @@ fn test_query_captures_with_many_nested_results_with_fields() { // Search expressions like `a ? a.b : null` let query = Query::new( - language, + &language, r#" ((ternary_expression condition: (identifier) @left @@ -3189,7 +3194,7 @@ fn test_query_captures_with_many_nested_results_with_fields() { source.push_str("} : null;\n"); let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(&source, None).unwrap(); let mut cursor = QueryCursor::new(); @@ -3248,7 +3253,7 @@ fn test_query_captures_with_too_many_nested_results() { // captured, but before the final `template_string` is found, those matches must // be buffered, in order to prevent captures from being returned out-of-order. let query = Query::new( - language, + &language, r#" ;; easy 👇 (call_expression @@ -3287,7 +3292,7 @@ fn test_query_captures_with_too_many_nested_results() { .trim(); let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); cursor.set_match_limit(32); @@ -3324,7 +3329,7 @@ fn test_query_captures_with_definite_pattern_containing_many_nested_matches() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, r#" (array "[" @l-bracket @@ -3350,7 +3355,7 @@ fn test_query_captures_with_definite_pattern_containing_many_nested_matches() { "; let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); @@ -3372,7 +3377,7 @@ fn test_query_captures_ordered_by_both_start_and_end_positions() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, r#" (call_expression) @call (member_expression) @member @@ -3386,7 +3391,7 @@ fn test_query_captures_ordered_by_both_start_and_end_positions() { "; let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); @@ -3412,7 +3417,7 @@ fn test_query_captures_with_matches_removed() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, r#" (binary_expression left: (identifier) @left @@ -3427,7 +3432,7 @@ fn test_query_captures_with_matches_removed() { "; let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); @@ -3456,7 +3461,7 @@ fn test_query_captures_with_matches_removed_before_they_finish() { // namespace_import node always has "*", "as" and then an identifier // for children, so captures will be emitted eagerly for this pattern. let query = Query::new( - language, + &language, r#" (namespace_import "*" @star @@ -3471,7 +3476,7 @@ fn test_query_captures_with_matches_removed_before_they_finish() { "; let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); @@ -3498,7 +3503,7 @@ fn test_query_captures_and_matches_iterators_are_fused() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, r#" (comment) @comment "#, @@ -3513,7 +3518,7 @@ fn test_query_captures_and_matches_iterators_are_fused() { "; let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); let mut captures = cursor.captures(&query, tree.root_node(), source.as_bytes()); @@ -3541,7 +3546,7 @@ fn test_query_text_callback_returns_chunks() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, r#" ((identifier) @leading_upper (#match? @leading_upper "^[A-Z][A-Z_]*[a-z]")) @@ -3587,7 +3592,7 @@ fn test_query_text_callback_returns_chunks() { ); let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); let captures = cursor.captures(&query, tree.root_node(), |node: Node| { @@ -3640,7 +3645,7 @@ fn test_query_start_byte_for_pattern() { source += patterns_2; source += patterns_3; - let query = Query::new(language, &source).unwrap(); + let query = Query::new(&language, &source).unwrap(); assert_eq!(query.start_byte_for_pattern(0), 0); assert_eq!(query.start_byte_for_pattern(5), patterns_1.len()); @@ -3655,7 +3660,7 @@ fn test_query_capture_names() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, r#" (if_statement condition: (parenthesized_expression (binary_expression @@ -3685,7 +3690,7 @@ fn test_query_lifetime_is_separate_from_nodes_lifetime() { let language = get_language("javascript"); let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); fn take_first_node_from_captures<'tree>( @@ -3696,7 +3701,7 @@ fn test_query_lifetime_is_separate_from_nodes_lifetime() { // Following 2 lines are redundant but needed to demonstrate // more understandable compiler error message let language = get_language("javascript"); - let query = Query::new(language, query).unwrap(); + let query = Query::new(&language, query).unwrap(); let mut cursor = QueryCursor::new(); let node = cursor .matches(&query, node, source.as_bytes()) @@ -3716,7 +3721,7 @@ fn test_query_lifetime_is_separate_from_nodes_lifetime() { node: Node<'tree>, ) -> Node<'tree> { let language = get_language("javascript"); - let query = Query::new(language, query).unwrap(); + let query = Query::new(&language, query).unwrap(); let mut cursor = QueryCursor::new(); let node = cursor .captures(&query, node, source.as_bytes()) @@ -3737,7 +3742,7 @@ fn test_query_lifetime_is_separate_from_nodes_lifetime() { fn test_query_with_no_patterns() { allocations::record(|| { let language = get_language("javascript"); - let query = Query::new(language, "").unwrap(); + let query = Query::new(&language, "").unwrap(); assert!(query.capture_names().is_empty()); assert_eq!(query.pattern_count(), 0); }); @@ -3748,7 +3753,7 @@ fn test_query_comments() { allocations::record(|| { let language = get_language("javascript"); let query = Query::new( - language, + &language, " ; this is my first comment ; i have two comments here @@ -3761,7 +3766,7 @@ fn test_query_comments() { let source = "function one() { }"; let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); let matches = cursor.matches(&query, tree.root_node(), source.as_bytes()); @@ -3777,7 +3782,7 @@ fn test_query_disable_pattern() { allocations::record(|| { let language = get_language("javascript"); let mut query = Query::new( - language, + &language, " (function_declaration name: (identifier) @name) @@ -3797,7 +3802,7 @@ fn test_query_disable_pattern() { let source = "class A { constructor() {} } function b() { return 1; }"; let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); let matches = cursor.matches(&query, tree.root_node(), source.as_bytes()); @@ -3816,7 +3821,7 @@ fn test_query_alternative_predicate_prefix() { allocations::record(|| { let language = get_language("c"); let query = Query::new( - language, + &language, r#" ((call_expression function: (identifier) @keyword @@ -3836,7 +3841,7 @@ fn test_query_alternative_predicate_prefix() { } "#; assert_query_matches( - language, + &language, &query, source, &[(0, vec![("keyword", "DEFUN"), ("function", "\"identity\"")])], @@ -3851,7 +3856,7 @@ fn test_query_random() { allocations::record(|| { let language = get_language("rust"); let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let mut cursor = QueryCursor::new(); cursor.set_match_limit(64); @@ -3872,7 +3877,7 @@ fn test_query_random() { let pattern = pattern_ast.to_string(); let expected_matches = pattern_ast.matches_in_tree(&test_tree); - let query = match Query::new(language, &pattern) { + let query = match Query::new(&language, &pattern) { Ok(query) => query, Err(e) => { panic!("failed to build query for pattern {pattern} - {e}. seed: {seed}"); @@ -4192,7 +4197,7 @@ fn test_query_is_pattern_guaranteed_at_step() { } } eprintln!(" query example: {:?}", row.description); - let query = Query::new(row.language, row.pattern).unwrap(); + let query = Query::new(&row.language, row.pattern).unwrap(); for (substring, is_definite) in row.results_by_substring { let offset = row.pattern.find(substring).unwrap(); assert_eq!( @@ -4288,7 +4293,7 @@ fn test_query_is_pattern_rooted() { } } eprintln!(" query example: {:?}", row.description); - let query = Query::new(language, row.pattern).unwrap(); + let query = Query::new(&language, row.pattern).unwrap(); assert_eq!( query.is_pattern_rooted(0), row.is_rooted, @@ -4385,7 +4390,7 @@ fn test_query_is_pattern_non_local() { } } eprintln!(" query example: {:?}", row.description); - let query = Query::new(row.language, row.pattern).unwrap(); + let query = Query::new(&row.language, row.pattern).unwrap(); assert_eq!( query.is_pattern_non_local(0), row.is_non_local, @@ -4615,7 +4620,7 @@ fn test_capture_quantifiers() { } } eprintln!(" query example: {:?}", row.description); - let query = Query::new(row.language, row.pattern).unwrap(); + let query = Query::new(&row.language, row.pattern).unwrap(); for (pattern, capture, expected_quantifier) in row.capture_quantifiers { let index = query.capture_index_for_name(capture).unwrap(); let actual_quantifier = query.capture_quantifiers(*pattern)[index as usize]; @@ -4707,10 +4712,10 @@ fn test_query_quantified_captures() { eprintln!(" quantified query example: {:?}", row.description); let mut parser = Parser::new(); - parser.set_language(row.language).unwrap(); + parser.set_language(&row.language).unwrap(); let tree = parser.parse(row.code, None).unwrap(); - let query = Query::new(row.language, row.pattern).unwrap(); + let query = Query::new(&row.language, row.pattern).unwrap(); let mut cursor = QueryCursor::new(); let matches = cursor.captures(&query, tree.root_node(), row.code.as_bytes()); @@ -4806,14 +4811,14 @@ fn test_query_max_start_depth() { allocations::record(|| { let language = get_language("c"); let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); for row in rows.iter() { eprintln!(" query example: {:?}", row.description); - let query = Query::new(language, row.pattern).unwrap(); + let query = Query::new(&language, row.pattern).unwrap(); cursor.set_max_start_depth(Some(row.depth)); let matches = cursor.matches(&query, tree.root_node(), source.as_bytes()); @@ -4833,7 +4838,7 @@ fn test_query_error_does_not_oob() { let language = get_language("javascript"); assert_eq!( - Query::new(language, "(clas").unwrap_err(), + Query::new(&language, "(clas").unwrap_err(), QueryError { row: 0, offset: 1, @@ -4848,7 +4853,7 @@ fn test_query_error_does_not_oob() { fn test_consecutive_zero_or_modifiers() { let language = get_language("javascript"); let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let zero_source = ""; let three_source = "/**/ /**/ /**/"; @@ -4864,7 +4869,7 @@ fn test_consecutive_zero_or_modifiers() { ]; for test in tests { - let query = Query::new(language, test).unwrap(); + let query = Query::new(&language, test).unwrap(); let mut cursor = QueryCursor::new(); let mut matches = cursor.matches(&query, zero_tree.root_node(), zero_source.as_bytes()); @@ -4936,10 +4941,10 @@ fn test_query_max_start_depth_more() { allocations::record(|| { let language = get_language("c"); let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse(source, None).unwrap(); let mut cursor = QueryCursor::new(); - let query = Query::new(language, "(compound_statement) @capture").unwrap(); + let query = Query::new(&language, "(compound_statement) @capture").unwrap(); let mut matches = cursor.matches(&query, tree.root_node(), source.as_bytes()); let node = matches.next().unwrap().captures[0].node; @@ -5035,7 +5040,7 @@ fn test_grammar_with_aliased_literal_query() { let language = get_test_language(&parser_name, &parser_code, None); let query = Query::new( - language, + &language, r#" (compound_statement "}" @bracket1) (expansion "}" @bracket2) diff --git a/cli/src/tests/text_provider_test.rs b/cli/src/tests/text_provider_test.rs index cb0b38f6..5006b20a 100644 --- a/cli/src/tests/text_provider_test.rs +++ b/cli/src/tests/text_provider_test.rs @@ -6,7 +6,7 @@ use tree_sitter::{Language, Node, Parser, Point, Query, QueryCursor, TextProvide fn parse_text(text: impl AsRef<[u8]>) -> (Tree, Language) { let language = get_language("c"); let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); (parser.parse(text, None).unwrap(), language) } @@ -17,7 +17,7 @@ where { let language = get_language("c"); let mut parser = Parser::new(); - parser.set_language(language).unwrap(); + parser.set_language(&language).unwrap(); let tree = parser.parse_with(callback, None).unwrap(); // eprintln!("{}", tree.clone().root_node().to_sexp()); assert_eq!("comment", tree.clone().root_node().child(0).unwrap().kind()); @@ -25,7 +25,7 @@ where } fn tree_query>(tree: &Tree, text: impl TextProvider, language: Language) { - let query = Query::new(language, "((comment) @c (#eq? @c \"// comment\"))").unwrap(); + let query = Query::new(&language, "((comment) @c (#eq? @c \"// comment\"))").unwrap(); let mut cursor = QueryCursor::new(); let mut captures = cursor.captures(&query, tree.root_node(), text); let (match_, idx) = captures.next().unwrap(); diff --git a/cli/src/tests/tree_test.rs b/cli/src/tests/tree_test.rs index f3792138..6a31188d 100644 --- a/cli/src/tests/tree_test.rs +++ b/cli/src/tests/tree_test.rs @@ -7,7 +7,7 @@ use tree_sitter::{InputEdit, Parser, Point, Range, Tree}; #[test] fn test_tree_edit() { let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); let tree = parser.parse(" abc !== def", None).unwrap(); assert_eq!( @@ -235,7 +235,7 @@ fn test_tree_edit() { #[test] fn test_tree_edit_with_included_ranges() { let mut parser = Parser::new(); - parser.set_language(get_language("html")).unwrap(); + parser.set_language(&get_language("html")).unwrap(); let source = "
<% if a %>a<% else %>b<% end %>
"; @@ -300,7 +300,7 @@ fn test_tree_edit_with_included_ranges() { #[test] fn test_tree_cursor() { let mut parser = Parser::new(); - parser.set_language(get_language("rust")).unwrap(); + parser.set_language(&get_language("rust")).unwrap(); let tree = parser .parse( @@ -379,7 +379,7 @@ fn test_tree_cursor() { #[test] fn test_tree_cursor_previous_sibling() { let mut parser = Parser::new(); - parser.set_language(get_language("rust")).unwrap(); + parser.set_language(&get_language("rust")).unwrap(); let text = " // Hi there @@ -418,7 +418,7 @@ fn test_tree_cursor_previous_sibling() { #[test] fn test_tree_cursor_fields() { let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); let tree = parser .parse("function /*1*/ bar /*2*/ () {}", None) @@ -455,7 +455,7 @@ fn test_tree_cursor_fields() { #[test] fn test_tree_cursor_child_for_point() { let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); let source = &" [ one, @@ -562,7 +562,7 @@ fn test_tree_cursor_child_for_point() { #[test] fn test_tree_node_equality() { let mut parser = Parser::new(); - parser.set_language(get_language("rust")).unwrap(); + parser.set_language(&get_language("rust")).unwrap(); let tree = parser.parse("struct A {}", None).unwrap(); let node1 = tree.root_node(); let node2 = tree.root_node(); @@ -576,7 +576,7 @@ fn test_get_changed_ranges() { let source_code = b"{a: null};\n".to_vec(); let mut parser = Parser::new(); - parser.set_language(get_language("javascript")).unwrap(); + parser.set_language(&get_language("javascript")).unwrap(); let tree = parser.parse(&source_code, None).unwrap(); assert_eq!( diff --git a/highlight/src/lib.rs b/highlight/src/lib.rs index 304d5e95..7c717fb6 100644 --- a/highlight/src/lib.rs +++ b/highlight/src/lib.rs @@ -267,7 +267,7 @@ impl HighlightConfiguration { // Construct a single query by concatenating the three query strings, but record the // range of pattern indices that belong to each individual string. - let mut query = Query::new(language, &query_source)?; + let mut query = Query::new(&language, &query_source)?; let mut locals_pattern_index = 0; let mut highlights_pattern_index = 0; for i in 0..(query.pattern_count()) { @@ -284,7 +284,7 @@ impl HighlightConfiguration { // Construct a separate query just for dealing with the 'combined injections'. // Disable the combined injection patterns in the main query. - let mut combined_injections_query = Query::new(language, injection_query)?; + let mut combined_injections_query = Query::new(&language, injection_query)?; let mut has_combined_queries = false; for pattern_index in 0..locals_pattern_index { let settings = query.property_settings(pattern_index); @@ -435,7 +435,7 @@ impl<'a> HighlightIterLayer<'a> { if highlighter.parser.set_included_ranges(&ranges).is_ok() { highlighter .parser - .set_language(config.language) + .set_language(&config.language) .map_err(|_| Error::InvalidLanguage)?; unsafe { highlighter.parser.set_cancellation_flag(cancellation_flag) }; diff --git a/lib/binding_rust/bindings.rs b/lib/binding_rust/bindings.rs index b7c0f2ed..c8650937 100644 --- a/lib/binding_rust/bindings.rs +++ b/lib/binding_rust/bindings.rs @@ -664,6 +664,14 @@ extern "C" { #[doc = " Set the maximum start depth for a query cursor.\n\n This prevents cursors from exploring children nodes at a certain depth.\n Note if a pattern includes many children, then they will still be checked.\n\n The zero max start depth value can be used as a special behavior and\n it helps to destructure a subtree by staying on a node and using captures\n for interested parts. Note that the zero max start depth only limit a search\n depth for a pattern's root node but other nodes that are parts of the pattern\n may be searched at any depth what defined by the pattern structure.\n\n Set to `UINT32_MAX` to remove the maximum start depth."] pub fn ts_query_cursor_set_max_start_depth(self_: *mut TSQueryCursor, max_start_depth: u32); } +extern "C" { + #[doc = " Get another reference to the given language."] + pub fn ts_language_copy(self_: *const TSLanguage) -> *const TSLanguage; +} +extern "C" { + #[doc = " Free any dynamically-allocated resources for this language, if\n this is the last reference."] + pub fn ts_language_delete(self_: *const TSLanguage); +} extern "C" { #[doc = " Get the number of distinct node types in the language."] pub fn ts_language_symbol_count(self_: *const TSLanguage) -> u32; diff --git a/lib/binding_rust/lib.rs b/lib/binding_rust/lib.rs index 29561926..359502b4 100644 --- a/lib/binding_rust/lib.rs +++ b/lib/binding_rust/lib.rs @@ -47,7 +47,7 @@ pub const PARSER_HEADER: &'static str = include_str!("../include/tree_sitter/par /// An opaque object that defines how to parse a particular language. The code for each /// `Language` is generated by the Tree-sitter CLI. #[doc(alias = "TSLanguage")] -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[derive(Debug, PartialEq, Eq, Hash)] #[repr(transparent)] pub struct Language(*const ffi::TSLanguage); @@ -385,6 +385,18 @@ impl Language { } } +impl Clone for Language { + fn clone(&self) -> Self { + unsafe { Self(ffi::ts_language_copy(self.0)) } + } +} + +impl Drop for Language { + fn drop(&mut self) { + unsafe { ffi::ts_language_delete(self.0) } + } +} + impl Parser { /// Create a new parser. pub fn new() -> Parser { @@ -403,7 +415,7 @@ impl Parser { /// and compare it to this library's [`LANGUAGE_VERSION`](LANGUAGE_VERSION) and /// [`MIN_COMPATIBLE_LANGUAGE_VERSION`](MIN_COMPATIBLE_LANGUAGE_VERSION) constants. #[doc(alias = "ts_parser_set_language")] - pub fn set_language(&mut self, language: Language) -> Result<(), LanguageError> { + pub fn set_language(&mut self, language: &Language) -> Result<(), LanguageError> { let version = language.version(); if version < MIN_COMPATIBLE_LANGUAGE_VERSION || version > LANGUAGE_VERSION { Err(LanguageError { version }) @@ -1553,7 +1565,7 @@ impl Query { /// The query is associated with a particular language, and can only be run /// on syntax nodes parsed with that language. References to Queries can be /// shared between multiple threads. - pub fn new(language: Language, source: &str) -> Result { + pub fn new(language: &Language, source: &str) -> Result { let mut error_offset = 0u32; let mut error_type: ffi::TSQueryError = 0; let bytes = source.as_bytes(); diff --git a/lib/include/tree_sitter/api.h b/lib/include/tree_sitter/api.h index eeecf317..7d4e7474 100644 --- a/lib/include/tree_sitter/api.h +++ b/lib/include/tree_sitter/api.h @@ -1013,6 +1013,17 @@ void ts_query_cursor_set_max_start_depth(TSQueryCursor *self, uint32_t max_start /* Section - Language */ /**********************/ +/** + * Get another reference to the given language. + */ +const TSLanguage *ts_language_copy(const TSLanguage *self); + +/** + * Free any dynamically-allocated resources for this language, if + * this is the last reference. + */ +void ts_language_delete(const TSLanguage *self); + /** * Get the number of distinct node types in the language. */ diff --git a/lib/src/language.c b/lib/src/language.c index 186edfa8..4842c037 100644 --- a/lib/src/language.c +++ b/lib/src/language.c @@ -1,6 +1,15 @@ #include "./language.h" #include +const TSLanguage *ts_language_copy(const TSLanguage *self) { + // TODO - increment reference count for wasm languages + return self; +} + +void ts_language_delete(const TSLanguage *_self) { + // TODO - decrement reference count for wasm languages +} + uint32_t ts_language_symbol_count(const TSLanguage *self) { return self->symbol_count + self->alias_count; } diff --git a/tags/src/lib.rs b/tags/src/lib.rs index 495a5221..3eee0957 100644 --- a/tags/src/lib.rs +++ b/tags/src/lib.rs @@ -117,7 +117,7 @@ struct LineInfo { impl TagsConfiguration { pub fn new(language: Language, tags_query: &str, locals_query: &str) -> Result { - let query = Query::new(language, &format!("{}{}", locals_query, tags_query))?; + let query = Query::new(&language, &format!("{}{}", locals_query, tags_query))?; let tags_query_offset = locals_query.len(); let mut tags_pattern_index = 0; @@ -265,7 +265,7 @@ impl TagsContext { cancellation_flag: Option<&'a AtomicUsize>, ) -> Result<(impl Iterator> + 'a, bool), Error> { self.parser - .set_language(config.language) + .set_language(&config.language) .map_err(|_| Error::InvalidLanguage)?; self.parser.reset(); unsafe { self.parser.set_cancellation_flag(cancellation_flag) };