chore: clippy

This commit is contained in:
dundargoc 2024-02-06 23:18:27 +01:00 committed by Amaan Qureshi
parent a1870b6013
commit c8bd6705cf
No known key found for this signature in database
GPG key ID: E67890ADC4227273
36 changed files with 467 additions and 462 deletions

View file

@ -18,7 +18,7 @@ jobs:
- run: cargo check --workspace --examples --tests --benches --bins
- run: cargo fmt -- --check
- run: cargo clippy --workspace
- run: cargo clippy --workspace --all-targets
check_c_warnings:
name: Check C warnings

View file

@ -15,7 +15,7 @@ lazy_static! {
static ref EXAMPLE_FILTER: Option<String> =
env::var("TREE_SITTER_BENCHMARK_EXAMPLE_FILTER").ok();
static ref REPETITION_COUNT: usize = env::var("TREE_SITTER_BENCHMARK_REPETITION_COUNT")
.map(|s| usize::from_str_radix(&s, 10).unwrap())
.map(|s| s.parse::<usize>().unwrap())
.unwrap_or(5);
static ref TEST_LOADER: Loader = Loader::with_parser_lib_path(SCRATCH_DIR.clone());
static ref EXAMPLE_AND_QUERY_PATHS_BY_LANGUAGE_DIR: BTreeMap<PathBuf, (Vec<PathBuf>, Vec<PathBuf>)> = {
@ -29,7 +29,7 @@ lazy_static! {
example_paths.extend(example_files.filter_map(|p| {
let p = p.unwrap().path();
if p.is_file() {
Some(p.to_owned())
Some(p)
} else {
None
}
@ -40,7 +40,7 @@ lazy_static! {
query_paths.extend(query_files.filter_map(|p| {
let p = p.unwrap().path();
if p.is_file() {
Some(p.to_owned())
Some(p)
} else {
None
}
@ -90,7 +90,7 @@ fn main() {
}
}
eprintln!("\nLanguage: {}", language_name);
eprintln!("\nLanguage: {language_name}");
let language = get_language(language_path);
parser.set_language(&language).unwrap();
@ -144,13 +144,13 @@ fn main() {
}
if let Some((average_normal, worst_normal)) = aggregate(&normal_speeds) {
eprintln!(" Average Speed (normal): {} bytes/ms", average_normal);
eprintln!(" Worst Speed (normal): {} bytes/ms", worst_normal);
eprintln!(" Average Speed (normal): {average_normal} bytes/ms");
eprintln!(" Worst Speed (normal): {worst_normal} bytes/ms");
}
if let Some((average_error, worst_error)) = aggregate(&error_speeds) {
eprintln!(" Average Speed (errors): {} bytes/ms", average_error);
eprintln!(" Worst Speed (errors): {} bytes/ms", worst_error);
eprintln!(" Average Speed (errors): {average_error} bytes/ms");
eprintln!(" Worst Speed (errors): {worst_error} bytes/ms");
}
all_normal_speeds.extend(normal_speeds);
@ -159,24 +159,24 @@ fn main() {
eprintln!("\n Overall");
if let Some((average_normal, worst_normal)) = aggregate(&all_normal_speeds) {
eprintln!(" Average Speed (normal): {} bytes/ms", average_normal);
eprintln!(" Worst Speed (normal): {} bytes/ms", worst_normal);
eprintln!(" Average Speed (normal): {average_normal} bytes/ms");
eprintln!(" Worst Speed (normal): {worst_normal} bytes/ms");
}
if let Some((average_error, worst_error)) = aggregate(&all_error_speeds) {
eprintln!(" Average Speed (errors): {} bytes/ms", average_error);
eprintln!(" Worst Speed (errors): {} bytes/ms", worst_error);
eprintln!(" Average Speed (errors): {average_error} bytes/ms");
eprintln!(" Worst Speed (errors): {worst_error} bytes/ms");
}
eprintln!();
}
fn aggregate(speeds: &Vec<usize>) -> Option<(usize, usize)> {
fn aggregate(speeds: &[usize]) -> Option<(usize, usize)> {
if speeds.is_empty() {
return None;
}
let mut total = 0;
let mut max = usize::MAX;
for speed in speeds.iter().cloned() {
for speed in speeds.iter().copied() {
total += speed;
if speed < max {
max = speed;
@ -193,7 +193,7 @@ fn parse(path: &Path, max_path_length: usize, mut action: impl FnMut(&[u8])) ->
);
let source_code = fs::read(path)
.with_context(|| format!("Failed to read {:?}", path))
.with_context(|| format!("Failed to read {path:?}"))
.unwrap();
let time = Instant::now();
for _ in 0..*REPETITION_COUNT {
@ -202,7 +202,7 @@ fn parse(path: &Path, max_path_length: usize, mut action: impl FnMut(&[u8])) ->
let duration = time.elapsed() / (*REPETITION_COUNT as u32);
let duration_ms = duration.as_millis();
let speed = source_code.len() as u128 / (duration_ms + 1);
eprintln!("time {} ms\tspeed {} bytes/ms", duration_ms as usize, speed);
eprintln!("time {} ms\tspeed {speed} bytes/ms", duration_ms as usize);
speed as usize
}
@ -210,6 +210,6 @@ fn get_language(path: &Path) -> Language {
let src_dir = GRAMMARS_DIR.join(path).join("src");
TEST_LOADER
.load_language_at_path(&src_dir, &[&src_dir])
.with_context(|| format!("Failed to load language at path {:?}", src_dir))
.with_context(|| format!("Failed to load language at path {src_dir:?}"))
.unwrap()
}

View file

@ -142,7 +142,7 @@ impl Loader {
debug_build: false,
#[cfg(feature = "wasm")]
wasm_store: Default::default(),
wasm_store: Mutex::default(),
}
}
@ -935,7 +935,7 @@ impl Loader {
#[cfg(feature = "wasm")]
pub fn use_wasm(&mut self, engine: tree_sitter::wasmtime::Engine) {
*self.wasm_store.lock().unwrap() = Some(tree_sitter::WasmStore::new(engine).unwrap())
*self.wasm_store.lock().unwrap() = Some(tree_sitter::WasmStore::new(engine).unwrap());
}
#[must_use]

View file

@ -436,14 +436,14 @@ mod tests {
let token_map = TokenConflictMap::new(
&grammar,
vec![
[Symbol::terminal(var("identifier"))]
.iter()
.cloned()
std::iter::once(&Symbol::terminal(var("identifier")))
.copied()
.collect(),
[Symbol::terminal(var("in"))].iter().cloned().collect(),
[Symbol::terminal(var("identifier"))]
.iter()
.cloned()
std::iter::once(&Symbol::terminal(var("in")))
.copied()
.collect(),
std::iter::once(&Symbol::terminal(var("identifier")))
.copied()
.collect(),
],
);

View file

@ -106,7 +106,7 @@ pub struct SyntaxGrammar {
#[cfg(test)]
impl ProductionStep {
pub fn new(symbol: Symbol) -> Self {
pub const fn new(symbol: Symbol) -> Self {
Self {
symbol,
precedence: Precedence::None,

View file

@ -971,7 +971,7 @@ mod tests {
"row {i}b: {:?} ~~ {:?}",
row.left,
row.right
)
);
}
}
@ -1032,6 +1032,7 @@ mod tests {
}
#[test]
#[allow(clippy::single_range_in_vec_init)]
fn test_character_set_get_ranges() {
struct Row {
chars: Vec<char>,
@ -1061,7 +1062,7 @@ mod tests {
chars,
ruled_out_chars,
expected_ranges,
} in table.iter()
} in &table
{
let ruled_out_chars = ruled_out_chars.iter().map(|c: &char| *c as u32).collect();
let mut set = CharacterSet::empty();

View file

@ -726,7 +726,7 @@ mod tests {
#[test]
fn test_node_types_simple() {
let node_types = get_node_types(InputGrammar {
let node_types = get_node_types(&InputGrammar {
variables: vec![
Variable {
name: "v1".to_string(),
@ -815,7 +815,7 @@ mod tests {
#[test]
fn test_node_types_simple_extras() {
let node_types = get_node_types(InputGrammar {
let node_types = get_node_types(&InputGrammar {
extra_symbols: vec![Rule::named("v3")],
variables: vec![
Variable {
@ -916,7 +916,7 @@ mod tests {
#[test]
fn test_node_types_with_supertypes() {
let node_types = get_node_types(InputGrammar {
let node_types = get_node_types(&InputGrammar {
supertype_symbols: vec!["_v2".to_string()],
variables: vec![
Variable {
@ -998,7 +998,7 @@ mod tests {
#[test]
fn test_node_types_for_children_without_fields() {
let node_types = get_node_types(InputGrammar {
let node_types = get_node_types(&InputGrammar {
variables: vec![
Variable {
name: "v1".to_string(),
@ -1090,7 +1090,7 @@ mod tests {
#[test]
fn test_node_types_with_inlined_rules() {
let node_types = get_node_types(InputGrammar {
let node_types = get_node_types(&InputGrammar {
variables_to_inline: vec!["v2".to_string()],
variables: vec![
Variable {
@ -1140,7 +1140,7 @@ mod tests {
#[test]
fn test_node_types_for_aliased_nodes() {
let node_types = get_node_types(InputGrammar {
let node_types = get_node_types(&InputGrammar {
variables: vec![
Variable {
name: "thing".to_string(),
@ -1210,7 +1210,7 @@ mod tests {
#[test]
fn test_node_types_with_multiple_valued_fields() {
let node_types = get_node_types(InputGrammar {
let node_types = get_node_types(&InputGrammar {
variables: vec![
Variable {
name: "a".to_string(),
@ -1272,7 +1272,7 @@ mod tests {
#[test]
fn test_node_types_with_fields_on_hidden_tokens() {
let node_types = get_node_types(InputGrammar {
let node_types = get_node_types(&InputGrammar {
variables: vec![Variable {
name: "script".to_string(),
kind: VariableType::Named,
@ -1298,7 +1298,7 @@ mod tests {
#[test]
fn test_node_types_with_multiple_rules_same_alias_name() {
let node_types = get_node_types(InputGrammar {
let node_types = get_node_types(&InputGrammar {
variables: vec![
Variable {
name: "script".to_string(),
@ -1418,7 +1418,7 @@ mod tests {
#[test]
fn test_node_types_with_tokens_aliased_to_match_rules() {
let node_types = get_node_types(InputGrammar {
let node_types = get_node_types(&InputGrammar {
variables: vec![
Variable {
name: "a".to_string(),
@ -1768,9 +1768,9 @@ mod tests {
);
}
fn get_node_types(grammar: InputGrammar) -> Vec<NodeInfoJSON> {
fn get_node_types(grammar: &InputGrammar) -> Vec<NodeInfoJSON> {
let (syntax_grammar, lexical_grammar, _, default_aliases) =
prepare_grammar(&grammar).unwrap();
prepare_grammar(grammar).unwrap();
let variable_info =
get_variable_info(&syntax_grammar, &lexical_grammar, &default_aliases).unwrap();
generate_node_types_json(

View file

@ -792,7 +792,7 @@ mod tests {
},
// nested groups
Row {
rules: vec![Rule::seq(vec![Rule::pattern(r#"([^x\\]|\\(.|\n))+"#, "")])],
rules: vec![Rule::seq(vec![Rule::pattern(r"([^x\\]|\\(.|\n))+", "")])],
separators: vec![],
examples: vec![("abcx", Some((0, "abc"))), ("abc\\0x", Some((0, "abc\\0")))],
},
@ -800,24 +800,24 @@ mod tests {
Row {
rules: vec![
// Escaped forward slash (used in JS because '/' is the regex delimiter)
Rule::pattern(r#"\/"#, ""),
Rule::pattern(r"\/", ""),
// Escaped quotes
Rule::pattern(r#"\"\'"#, ""),
// Quote preceded by a literal backslash
Rule::pattern(r#"[\\']+"#, ""),
Rule::pattern(r"[\\']+", ""),
],
separators: vec![],
examples: vec![
("/", Some((0, "/"))),
("\"\'", Some((1, "\"\'"))),
(r#"'\'a"#, Some((2, r#"'\'"#))),
(r"'\'a", Some((2, r"'\'"))),
],
},
// unicode property escapes
Row {
rules: vec![
Rule::pattern(r#"\p{L}+\P{L}+"#, ""),
Rule::pattern(r#"\p{White_Space}+\P{White_Space}+[\p{White_Space}]*"#, ""),
Rule::pattern(r"\p{L}+\P{L}+", ""),
Rule::pattern(r"\p{White_Space}+\P{White_Space}+[\p{White_Space}]*", ""),
],
separators: vec![],
examples: vec![
@ -827,17 +827,17 @@ mod tests {
},
// unicode property escapes in bracketed sets
Row {
rules: vec![Rule::pattern(r#"[\p{L}\p{Nd}]+"#, "")],
rules: vec![Rule::pattern(r"[\p{L}\p{Nd}]+", "")],
separators: vec![],
examples: vec![("abΨ12٣٣, ok", Some((0, "abΨ12٣٣")))],
},
// unicode character escapes
Row {
rules: vec![
Rule::pattern(r#"\u{00dc}"#, ""),
Rule::pattern(r#"\U{000000dd}"#, ""),
Rule::pattern(r#"\u00de"#, ""),
Rule::pattern(r#"\U000000df"#, ""),
Rule::pattern(r"\u{00dc}", ""),
Rule::pattern(r"\U{000000dd}", ""),
Rule::pattern(r"\u00de", ""),
Rule::pattern(r"\U000000df", ""),
],
separators: vec![],
examples: vec![
@ -851,13 +851,13 @@ mod tests {
Row {
rules: vec![
// Un-escaped curly braces
Rule::pattern(r#"u{[0-9a-fA-F]+}"#, ""),
Rule::pattern(r"u{[0-9a-fA-F]+}", ""),
// Already-escaped curly braces
Rule::pattern(r#"\{[ab]{3}\}"#, ""),
Rule::pattern(r"\{[ab]{3}\}", ""),
// Unicode codepoints
Rule::pattern(r#"\u{1000A}"#, ""),
Rule::pattern(r"\u{1000A}", ""),
// Unicode codepoints (lowercase)
Rule::pattern(r#"\u{1000b}"#, ""),
Rule::pattern(r"\u{1000b}", ""),
],
separators: vec![],
examples: vec![
@ -957,7 +957,7 @@ mod tests {
})
.unwrap();
for (haystack, needle) in examples.iter() {
for (haystack, needle) in examples {
assert_eq!(simulate_nfa(&grammar, haystack), *needle);
}
}

View file

@ -402,7 +402,7 @@ mod test {
assert_eq!(
lexical_grammar.variables,
vec![Variable::anonymous("hello", Rule::string("hello")),]
)
);
}
#[test]

View file

@ -266,7 +266,7 @@ mod tests {
..Default::default()
};
let inline_map = process_inlines(&grammar, &Default::default()).unwrap();
let inline_map = process_inlines(&grammar, &LexicalGrammar::default()).unwrap();
// Nothing to inline at step 0.
assert!(inline_map
@ -362,7 +362,7 @@ mod tests {
..Default::default()
};
let inline_map = process_inlines(&grammar, &Default::default()).unwrap();
let inline_map = process_inlines(&grammar, &LexicalGrammar::default()).unwrap();
let productions: Vec<&Production> = inline_map
.inlined_productions(&grammar.variables[0].productions[0], 1)
@ -370,7 +370,7 @@ mod tests {
.collect();
assert_eq!(
productions.iter().cloned().cloned().collect::<Vec<_>>(),
productions.iter().copied().cloned().collect::<Vec<_>>(),
vec![
Production {
dynamic_precedence: 0,
@ -461,7 +461,7 @@ mod tests {
..Default::default()
};
let inline_map = process_inlines(&grammar, &Default::default()).unwrap();
let inline_map = process_inlines(&grammar, &LexicalGrammar::default()).unwrap();
let productions: Vec<_> = inline_map
.inlined_productions(&grammar.variables[0].productions[0], 0)
@ -469,7 +469,7 @@ mod tests {
.collect();
assert_eq!(
productions.iter().cloned().cloned().collect::<Vec<_>>(),
productions.iter().copied().cloned().collect::<Vec<_>>(),
vec![Production {
dynamic_precedence: 0,
steps: vec![

View file

@ -151,6 +151,7 @@ impl Rule {
}
impl Alias {
#[must_use]
pub const fn kind(&self) -> VariableType {
if self.is_named {
VariableType::Named
@ -161,6 +162,7 @@ impl Alias {
}
impl Precedence {
#[must_use]
pub const fn is_none(&self) -> bool {
matches!(self, Self::None)
}
@ -168,48 +170,59 @@ impl Precedence {
#[cfg(test)]
impl Rule {
pub fn terminal(index: usize) -> Self {
#[must_use]
pub const fn terminal(index: usize) -> Self {
Self::Symbol(Symbol::terminal(index))
}
pub fn non_terminal(index: usize) -> Self {
#[must_use]
pub const fn non_terminal(index: usize) -> Self {
Self::Symbol(Symbol::non_terminal(index))
}
pub fn external(index: usize) -> Self {
#[must_use]
pub const fn external(index: usize) -> Self {
Self::Symbol(Symbol::external(index))
}
#[must_use]
pub fn named(name: &'static str) -> Self {
Self::NamedSymbol(name.to_string())
}
#[must_use]
pub fn string(value: &'static str) -> Self {
Self::String(value.to_string())
}
#[must_use]
pub fn pattern(value: &'static str, flags: &'static str) -> Self {
Self::Pattern(value.to_string(), flags.to_string())
}
}
impl Symbol {
#[must_use]
pub fn is_terminal(&self) -> bool {
self.kind == SymbolType::Terminal
}
#[must_use]
pub fn is_non_terminal(&self) -> bool {
self.kind == SymbolType::NonTerminal
}
#[must_use]
pub fn is_external(&self) -> bool {
self.kind == SymbolType::External
}
#[must_use]
pub fn is_eof(&self) -> bool {
self.kind == SymbolType::End
}
#[must_use]
pub const fn non_terminal(index: usize) -> Self {
Self {
kind: SymbolType::NonTerminal,
@ -217,6 +230,7 @@ impl Symbol {
}
}
#[must_use]
pub const fn terminal(index: usize) -> Self {
Self {
kind: SymbolType::Terminal,
@ -224,6 +238,7 @@ impl Symbol {
}
}
#[must_use]
pub const fn external(index: usize) -> Self {
Self {
kind: SymbolType::External,
@ -231,6 +246,7 @@ impl Symbol {
}
}
#[must_use]
pub const fn end() -> Self {
Self {
kind: SymbolType::End,
@ -238,6 +254,7 @@ impl Symbol {
}
}
#[must_use]
pub const fn end_of_nonterminal_extra() -> Self {
Self {
kind: SymbolType::EndOfNonTerminalExtra,
@ -247,6 +264,7 @@ impl Symbol {
}
impl From<Symbol> for Rule {
#[must_use]
fn from(symbol: Symbol) -> Self {
Self::Symbol(symbol)
}

View file

@ -92,7 +92,9 @@ pub fn run_tests_at_path(
parser.stop_printing_dot_graphs();
if !failures.is_empty() {
if failures.is_empty() {
Ok(())
} else {
println!();
if update {
@ -122,8 +124,6 @@ pub fn run_tests_at_path(
}
Err(anyhow!(""))
}
} else {
Ok(())
}
}
@ -566,7 +566,7 @@ mod tests {
fn test_parse_test_content_simple() {
let entry = parse_test_content(
"the-filename".to_string(),
r#"
r"
===============
The first test
===============
@ -584,7 +584,7 @@ The second test
d
---
(d)
"#
"
.trim(),
None,
);
@ -620,7 +620,7 @@ d
fn test_parse_test_content_with_dashes_in_source_code() {
let entry = parse_test_content(
"the-filename".to_string(),
r#"
r"
==================
Code with dashes
==================
@ -641,7 +641,7 @@ abc
-------------------
(c (d))
"#
"
.trim(),
None,
);
@ -678,7 +678,7 @@ abc
assert_eq!(format_sexp(""), "");
assert_eq!(
format_sexp("(a b: (c) (d) e: (f (g (h (MISSING i)))))"),
r#"
r"
(a
b: (c)
(d)
@ -686,7 +686,7 @@ abc
(g
(h
(MISSING i)))))
"#
"
.trim()
);
assert_eq!(format_sexp("()"), "()");
@ -694,12 +694,12 @@ abc
assert_eq!(format_sexp("(A (U (B)))"), "(A\n (U\n (B)))");
assert_eq!(
format_sexp("(program (ERROR (UNEXPECTED ' ')) (identifier))"),
r#"
r"
(program
(ERROR
(UNEXPECTED ' '))
(identifier))
"#
"
.trim()
);
}
@ -726,7 +726,7 @@ abc
write_tests_to_buffer(&mut buffer, &corrected_entries).unwrap();
assert_eq!(
String::from_utf8(buffer).unwrap(),
r#"
r"
================================================================================
title 1
================================================================================
@ -742,7 +742,7 @@ input 2
--------------------------------------------------------------------------------
output 2
"#
"
.trim_start()
.to_string()
);
@ -826,7 +826,7 @@ code
fn test_parse_test_content_with_suffixes() {
let entry = parse_test_content(
"the-filename".to_string(),
r#"
r"
==================asdf\()[]|{}*+?^$.-
First test
==================asdf\()[]|{}*+?^$.-
@ -865,7 +865,7 @@ NOT A TEST HEADER
---asdf\()[]|{}*+?^$.-
(a)
"#
"
.trim(),
None,
);
@ -899,7 +899,7 @@ NOT A TEST HEADER
},
TestEntry::Example {
name: "Test name with = symbol".to_string(),
input: expected_input.clone(),
input: expected_input,
output: "(a)".to_string(),
header_delim_len: 25,
divider_delim_len: 3,
@ -915,7 +915,7 @@ NOT A TEST HEADER
fn test_parse_test_content_with_newlines_in_test_names() {
let entry = parse_test_content(
"the-filename".to_string(),
r#"
r"
===============
name
with
@ -931,7 +931,7 @@ name with === signs
code with ----
---
(d)
"#,
",
None,
);

View file

@ -61,7 +61,7 @@ fn test_node_in_fut() {
#[test]
fn test_node_and_cursor_ref_in_fut() {
let (_, pended) = tokio_like_spawn(async {
let ((), pended) = tokio_like_spawn(async {
let mut parser = Parser::new();
let language = get_language("bash");
parser.set_language(&language).unwrap();
@ -100,7 +100,7 @@ fn test_node_and_cursor_ref_in_fut() {
#[test]
fn test_node_and_cursor_ref_in_fut_with_fut_fabrics() {
let (_, pended) = tokio_like_spawn(async {
let ((), pended) = tokio_like_spawn(async {
let mut parser = Parser::new();
let language = get_language("bash");
parser.set_language(&language).unwrap();
@ -177,8 +177,8 @@ fn test_node_and_cursor_ref_in_fut_with_inner_spawns() {
}
};
let (_, p1) = tokio_like_spawn(fut_val()).await.unwrap();
let (_, p2) = tokio_like_spawn(fut_ref()).await.unwrap();
let ((), p1) = tokio_like_spawn(fut_val()).await.unwrap();
let ((), p2) = tokio_like_spawn(fut_ref()).await.unwrap();
cursor_ref.goto_first_child();
@ -237,7 +237,7 @@ async fn yield_now() {
}
}
SimpleYieldNow { yielded: false }.await
SimpleYieldNow { yielded: false }.await;
}
pub fn noop_waker() -> Waker {
@ -260,7 +260,8 @@ struct JoinHandle<T> {
}
impl<T> JoinHandle<T> {
fn new(data: T) -> Self {
#[must_use]
const fn new(data: T) -> Self {
Self { data: Some(data) }
}

View file

@ -114,12 +114,11 @@ fn test_language_corpus(
.join("corpus");
}
let error_corpus_file = error_corpus_dir.join(&format!("{}_errors.txt", language_name));
let template_corpus_file =
template_corpus_dir.join(&format!("{}_templates.txt", language_name));
let error_corpus_file = error_corpus_dir.join(format!("{language_name}_errors.txt"));
let template_corpus_file = template_corpus_dir.join(format!("{language_name}_templates.txt"));
let main_tests = parse_tests(&corpus_dir).unwrap();
let error_tests = parse_tests(&error_corpus_file).unwrap_or(TestEntry::default());
let template_tests = parse_tests(&template_corpus_file).unwrap_or(TestEntry::default());
let error_tests = parse_tests(&error_corpus_file).unwrap_or_default();
let template_tests = parse_tests(&template_corpus_file).unwrap_or_default();
let mut tests = flatten_tests(main_tests);
tests.extend(flatten_tests(error_tests));
tests.extend(flatten_tests(template_tests).into_iter().map(|mut t| {
@ -127,7 +126,7 @@ fn test_language_corpus(
t
}));
let mut skipped = skipped.map(|x| HashMap::<&str, usize>::from_iter(x.iter().map(|x| (*x, 0))));
let mut skipped = skipped.map(|x| x.iter().map(|x| (*x, 0)).collect::<HashMap<&str, usize>>());
let language_path = if subdir.is_empty() {
language_name.to_string()
@ -141,7 +140,7 @@ fn test_language_corpus(
let dump_edits = env::var("TREE_SITTER_DUMP_EDITS").is_ok();
if log_seed {
println!(" start seed: {}", start_seed);
println!(" start seed: {start_seed}");
}
println!();
@ -173,7 +172,7 @@ fn test_language_corpus(
println!("Incorrect initial parse for {test_name}");
print_diff_key();
print_diff(&actual_output, &test.output);
println!("");
println!();
return false;
}
@ -213,7 +212,7 @@ fn test_language_corpus(
}
if log_seed {
println!(" {test_index}.{trial:<2} seed: {}", seed);
println!(" {test_index}.{trial:<2} seed: {seed}");
}
if dump_edits {
@ -260,7 +259,7 @@ fn test_language_corpus(
println!("Incorrect parse for {test_name} - seed {seed}");
print_diff_key();
print_diff(&actual_output, &test.output);
println!("");
println!();
return false;
}
@ -281,14 +280,15 @@ fn test_language_corpus(
}
}
if failure_count > 0 {
panic!("{} {} corpus tests failed", failure_count, language_name);
}
assert!(
failure_count == 0,
"{failure_count} {language_name} corpus tests failed"
);
if let Some(skipped) = skipped.as_mut() {
skipped.retain(|_, v| *v == 0);
if skipped.len() > 0 {
if !skipped.is_empty() {
println!("Non matchable skip definitions:");
for k in skipped.keys() {
println!(" {k}");
@ -303,7 +303,7 @@ fn test_feature_corpus_files() {
let test_grammars_dir = fixtures_dir().join("test_grammars");
let mut failure_count = 0;
for entry in fs::read_dir(&test_grammars_dir).unwrap() {
for entry in fs::read_dir(test_grammars_dir).unwrap() {
let entry = entry.unwrap();
if !entry.metadata().unwrap().is_dir() {
continue;
@ -331,7 +331,7 @@ fn test_feature_corpus_files() {
continue;
}
eprintln!("test language: {:?}", language_name);
eprintln!("test language: {language_name:?}");
let expected_message = fs::read_to_string(&error_message_path)
.unwrap()
@ -340,24 +340,17 @@ fn test_feature_corpus_files() {
let actual_message = e.to_string().replace("\r\n", "\n");
if expected_message != actual_message {
eprintln!(
"Unexpected error message.\n\nExpected:\n\n{}\nActual:\n\n{}\n",
expected_message, actual_message
"Unexpected error message.\n\nExpected:\n\n{expected_message}\nActual:\n\n{actual_message}\n",
);
failure_count += 1;
}
} else {
eprintln!(
"Expected error message but got none for test grammar '{}'",
language_name
);
eprintln!("Expected error message but got none for test grammar '{language_name}'",);
failure_count += 1;
}
} else {
if let Err(e) = &generate_result {
eprintln!(
"Unexpected error for test grammar '{}':\n{}",
language_name, e
);
eprintln!("Unexpected error for test grammar '{language_name}':\n{e}",);
failure_count += 1;
continue;
}
@ -369,7 +362,7 @@ fn test_feature_corpus_files() {
let tests = flatten_tests(test);
if !tests.is_empty() {
eprintln!("test language: {:?}", language_name);
eprintln!("test language: {language_name:?}");
}
for test in tests {
@ -389,7 +382,7 @@ fn test_feature_corpus_files() {
} else {
print_diff_key();
print_diff(&actual_output, &test.output);
println!("");
println!();
false
}
});
@ -401,12 +394,11 @@ fn test_feature_corpus_files() {
}
}
}
if failure_count > 0 {
panic!("{} corpus tests failed", failure_count);
}
assert!(failure_count == 0, "{failure_count} corpus tests failed");
}
fn check_consistent_sizes(tree: &Tree, input: &Vec<u8>) {
fn check_consistent_sizes(tree: &Tree, input: &[u8]) {
fn check(node: Node, line_offsets: &Vec<usize>) {
let start_byte = node.start_byte();
let end_byte = node.end_byte();
@ -454,7 +446,7 @@ fn check_consistent_sizes(tree: &Tree, input: &Vec<u8>) {
let mut line_offsets = vec![0];
for (i, c) in input.iter().enumerate() {
if *c == '\n' as u8 {
if *c == b'\n' {
line_offsets.push(i + 1);
}
}
@ -462,7 +454,7 @@ fn check_consistent_sizes(tree: &Tree, input: &Vec<u8>) {
check(tree.root_node(), &line_offsets);
}
fn check_changed_ranges(old_tree: &Tree, new_tree: &Tree, input: &Vec<u8>) -> Result<(), String> {
fn check_changed_ranges(old_tree: &Tree, new_tree: &Tree, input: &[u8]) -> Result<(), String> {
let changed_ranges = old_tree.changed_ranges(new_tree).collect::<Vec<_>>();
let old_scope_sequence = ScopeSequence::new(old_tree);
let new_scope_sequence = ScopeSequence::new(new_tree);
@ -478,13 +470,12 @@ fn check_changed_ranges(old_tree: &Tree, new_tree: &Tree, input: &Vec<u8>) -> Re
for range in &changed_ranges {
if range.end_byte > byte_range.end || range.end_point > point_range.end {
return Err(format!(
"changed range extends outside of the old and new trees {:?}",
range
"changed range extends outside of the old and new trees {range:?}",
));
}
}
old_scope_sequence.check_changes(&new_scope_sequence, &input, &changed_ranges)
old_scope_sequence.check_changes(&new_scope_sequence, input, &changed_ranges)
}
fn set_included_ranges(parser: &mut Parser, input: &[u8], delimiters: Option<(&str, &str)>) {
@ -537,9 +528,9 @@ fn get_parser(session: &mut Option<util::LogSession>, log_filename: &str) -> Par
if *LOG_ENABLED {
parser.set_logger(Some(Box::new(|log_type, msg| {
if log_type == LogType::Lex {
eprintln!(" {}", msg);
eprintln!(" {msg}");
} else {
eprintln!("{}", msg);
eprintln!("{msg}");
}
})));
} else if *LOG_GRAPH_ENABLED {

View file

@ -20,9 +20,9 @@ fn issue_2162_out_of_bound() {
#[test]
fn issue_2107_first_child_group_anchor_had_no_effect() {
let language = get_language("c");
let source_code = indoc! {r#"
let source_code = indoc! {r"
void fun(int a, char b, int c) { };
"#};
"};
let query = indoc! {r#"
(parameter_list
.

View file

@ -30,7 +30,7 @@ struct AllocationRecorder {
}
thread_local! {
static RECORDER: AllocationRecorder = Default::default();
static RECORDER: AllocationRecorder = AllocationRecorder::default();
}
extern "C" {
@ -60,12 +60,10 @@ pub fn record<T>(f: impl FnOnce() -> T) -> T {
.map(|e| e.1)
.collect::<Vec<_>>()
});
if !outstanding_allocation_indices.is_empty() {
panic!(
"Leaked allocation indices: {:?}",
outstanding_allocation_indices
);
}
assert!(
outstanding_allocation_indices.is_empty(),
"Leaked allocation indices: {outstanding_allocation_indices:?}"
);
value
}
@ -83,9 +81,7 @@ fn record_alloc(ptr: *mut c_void) {
}
fn record_dealloc(ptr: *mut c_void) {
if ptr.is_null() {
panic!("Zero pointer deallocation!");
}
assert!(!ptr.is_null(), "Zero pointer deallocation!");
RECORDER.with(|recorder| {
if recorder.enabled.load(SeqCst) {
recorder

View file

@ -39,7 +39,7 @@ lazy_static! {
"unknown"
};
let machine = format!("{}-{}-{}-{}-{}", std::env::consts::ARCH, std::env::consts::OS, vendor, env, endian);
let machine = format!("{}-{}-{vendor}-{env}-{endian}", std::env::consts::ARCH, std::env::consts::OS);
let result = SCRATCH_BASE_DIR.join(machine);
fs::create_dir_all(&result).unwrap();
result

View file

@ -10,7 +10,8 @@ pub struct ReadRecorder<'a> {
}
impl<'a> ReadRecorder<'a> {
pub fn new(content: &'a Vec<u8>) -> Self {
#[must_use]
pub const fn new(content: &'a Vec<u8>) -> Self {
Self {
content,
indices_read: Vec::new(),
@ -31,7 +32,7 @@ impl<'a> ReadRecorder<'a> {
pub fn strings_read(&self) -> Vec<&'a str> {
let mut result = Vec::new();
let mut last_range: Option<Range<usize>> = None;
for index in self.indices_read.iter() {
for index in &self.indices_read {
if let Some(ref mut range) = &mut last_range {
if range.end == *index {
range.end += 1;
@ -44,13 +45,13 @@ impl<'a> ReadRecorder<'a> {
}
}
if let Some(range) = last_range {
result.push(str::from_utf8(&self.content[range.clone()]).unwrap());
result.push(str::from_utf8(&self.content[range]).unwrap());
}
result
}
}
pub fn invert_edit(input: &Vec<u8>, edit: &Edit) -> Edit {
pub fn invert_edit(input: &[u8], edit: &Edit) -> Edit {
let position = edit.position;
let removed_content = &input[position..(position + edit.deleted_length)];
Edit {
@ -60,7 +61,7 @@ pub fn invert_edit(input: &Vec<u8>, edit: &Edit) -> Edit {
}
}
pub fn get_random_edit(rand: &mut Rand, input: &Vec<u8>) -> Edit {
pub fn get_random_edit(rand: &mut Rand, input: &[u8]) -> Edit {
let choice = rand.unsigned(10);
if choice < 2 {
// Insert text at end

View file

@ -19,11 +19,11 @@ lazy_static! {
};
}
pub fn test_loader<'a>() -> &'a Loader {
&*TEST_LOADER
pub fn test_loader() -> &'static Loader {
&TEST_LOADER
}
pub fn fixtures_dir<'a>() -> &'static Path {
pub fn fixtures_dir() -> &'static Path {
&FIXTURES_DIR
}
@ -48,12 +48,11 @@ pub fn get_highlight_config(
let language = get_language(language_name);
let queries_path = get_language_queries_path(language_name);
let highlights_query = fs::read_to_string(queries_path.join("highlights.scm")).unwrap();
let injections_query = if let Some(injection_query_filename) = injection_query_filename {
fs::read_to_string(queries_path.join(injection_query_filename)).unwrap()
} else {
String::new()
};
let locals_query = fs::read_to_string(queries_path.join("locals.scm")).unwrap_or(String::new());
let injections_query =
injection_query_filename.map_or_else(String::new, |injection_query_filename| {
fs::read_to_string(queries_path.join(injection_query_filename)).unwrap()
});
let locals_query = fs::read_to_string(queries_path.join("locals.scm")).unwrap_or_default();
let mut result = HighlightConfiguration::new(
language,
language_name,
@ -63,7 +62,7 @@ pub fn get_highlight_config(
false,
)
.unwrap();
result.configure(&highlight_names);
result.configure(highlight_names);
result
}
@ -71,7 +70,7 @@ pub fn get_tags_config(language_name: &str) -> TagsConfiguration {
let language = get_language(language_name);
let queries_path = get_language_queries_path(language_name);
let tags_query = fs::read_to_string(queries_path.join("tags.scm")).unwrap();
let locals_query = fs::read_to_string(queries_path.join("locals.scm")).unwrap_or(String::new());
let locals_query = fs::read_to_string(queries_path.join("locals.scm")).unwrap_or_default();
TagsConfiguration::new(language, &tags_query, &locals_query).unwrap()
}
@ -99,7 +98,7 @@ pub fn get_test_language(name: &str, parser_code: &str, path: Option<&Path>) ->
let header_path = src_dir.join("tree_sitter");
fs::create_dir_all(&header_path).unwrap();
fs::write(&header_path.join("parser.h"), tree_sitter::PARSER_HEADER)
fs::write(header_path.join("parser.h"), tree_sitter::PARSER_HEADER)
.with_context(|| {
format!(
"Failed to write {:?}",

View file

@ -26,7 +26,7 @@ fn int_env_var(name: &'static str) -> Option<usize> {
env::var(name).ok().and_then(|e| e.parse().ok())
}
pub(crate) fn new_seed() -> usize {
pub fn new_seed() -> usize {
int_env_var("TREE_SITTER_SEED").unwrap_or_else(|| {
let mut rng = rand::thread_rng();
rng.gen::<usize>()

View file

@ -19,7 +19,7 @@ pub struct Match<'a, 'tree> {
pub last_node: Option<Node<'tree>>,
}
const CAPTURE_NAMES: &'static [&'static str] = &[
const CAPTURE_NAMES: &[&str] = &[
"one", "two", "three", "four", "five", "six", "seven", "eight",
];
@ -57,12 +57,11 @@ impl Pattern {
children: roots,
};
if pattern.children.len() == 1 {
pattern = pattern.children.pop().unwrap();
}
if pattern.children.len() == 1 ||
// In a parenthesized list of sibling patterns, the first
// sibling can't be an anonymous `_` wildcard.
else if pattern.children[0].kind == Some("_") && !pattern.children[0].named {
(pattern.children[0].kind == Some("_") && !pattern.children[0].named)
{
pattern = pattern.children.pop().unwrap();
}
// In a parenthesized list of sibling patterns, the first
@ -123,22 +122,16 @@ impl Pattern {
}
}
pub fn to_string(&self) -> String {
let mut result = String::new();
self.write_to_string(&mut result, 0);
result
}
fn write_to_string(&self, string: &mut String, indent: usize) {
if let Some(field) = self.field {
write!(string, "{}: ", field).unwrap();
write!(string, "{field}: ").unwrap();
}
if self.named {
string.push('(');
let mut has_contents = false;
if let Some(kind) = &self.kind {
write!(string, "{}", kind).unwrap();
write!(string, "{kind}").unwrap();
has_contents = true;
}
for child in &self.children {
@ -154,11 +147,11 @@ impl Pattern {
} else if self.kind == Some("_") {
string.push('_');
} else {
write!(string, "\"{}\"", self.kind.unwrap().replace("\"", "\\\"")).unwrap();
write!(string, "\"{}\"", self.kind.unwrap().replace('\"', "\\\"")).unwrap();
}
if let Some(capture) = &self.capture {
write!(string, " @{}", capture).unwrap();
write!(string, " @{capture}").unwrap();
}
}
@ -214,11 +207,10 @@ impl Pattern {
// Create a match for the current node.
let mat = Match {
captures: if let Some(name) = &self.capture {
vec![(name.as_str(), node)]
} else {
Vec::new()
},
captures: self
.capture
.as_ref()
.map_or_else(Vec::new, |name| vec![(name.as_str(), node)]),
last_node: Some(node),
};
@ -246,7 +238,7 @@ impl Pattern {
new_match_states.push((*pattern_index + 1, combined_match));
} else {
let mut existing = false;
for existing_match in finished_matches.iter_mut() {
for existing_match in &mut finished_matches {
if existing_match.captures == combined_match.captures {
if child_pattern.capture.is_some() {
existing_match.last_node = combined_match.last_node;
@ -271,6 +263,14 @@ impl Pattern {
}
}
impl ToString for Pattern {
fn to_string(&self) -> String {
let mut result = String::new();
self.write_to_string(&mut result, 0);
result
}
}
impl<'a, 'tree> PartialOrd for Match<'a, 'tree> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
@ -314,11 +314,11 @@ pub fn assert_query_matches(
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());
pretty_assertions::assert_eq!(collect_matches(matches, &query, source), expected);
let matches = cursor.matches(query, tree.root_node(), source.as_bytes());
pretty_assertions::assert_eq!(collect_matches(matches, query, source), expected);
pretty_assertions::assert_eq!(cursor.did_exceed_match_limit(), false);
}
@ -331,7 +331,7 @@ pub fn collect_matches<'a>(
.map(|m| {
(
m.pattern_index,
format_captures(m.captures.iter().cloned(), query, source),
format_captures(m.captures.iter().copied(), query, source),
)
})
.collect()

View file

@ -11,7 +11,7 @@ pub struct Rand(StdRng);
impl Rand {
pub fn new(seed: usize) -> Self {
Rand(StdRng::seed_from_u64(seed as u64))
Self(StdRng::seed_from_u64(seed as u64))
}
pub fn unsigned(&mut self, max: usize) -> usize {
@ -24,9 +24,9 @@ impl Rand {
for i in 0..word_count {
if i > 0 {
if self.unsigned(5) == 0 {
result.push('\n' as u8);
result.push(b'\n');
} else {
result.push(' ' as u8);
result.push(b' ');
}
}
if self.unsigned(3) == 0 {
@ -34,7 +34,7 @@ impl Rand {
result.push(OPERATORS[index] as u8);
} else {
for _ in 0..self.unsigned(8) {
result.push(self.0.sample(Alphanumeric) as u8);
result.push(self.0.sample(Alphanumeric));
}
}
}

View file

@ -7,7 +7,7 @@ type ScopeStack = Vec<&'static str>;
impl ScopeSequence {
pub fn new(tree: &Tree) -> Self {
let mut result = ScopeSequence(Vec::new());
let mut result = Self(Vec::new());
let mut scope_stack = Vec::new();
let mut cursor = tree.walk();
@ -40,9 +40,9 @@ impl ScopeSequence {
pub fn check_changes(
&self,
other: &ScopeSequence,
text: &Vec<u8>,
known_changed_ranges: &Vec<Range>,
other: &Self,
text: &[u8],
known_changed_ranges: &[Range],
) -> Result<(), String> {
let mut position = Point { row: 0, column: 0 };
for i in 0..(self.0.len().max(other.0.len())) {
@ -54,7 +54,7 @@ impl ScopeSequence {
.find(|range| range.start_point <= position && position < range.end_point);
if containing_range.is_none() {
let line = &text[(i - position.column)..]
.split(|c| *c == '\n' as u8)
.split(|c| *c == b'\n')
.next()
.unwrap();
return Err(format!(
@ -78,7 +78,7 @@ impl ScopeSequence {
}
}
if text[i] == '\n' as u8 {
if text[i] == b'\n' {
position.row += 1;
position.column = 0;
} else {

View file

@ -49,12 +49,12 @@ lazy_static! {
"variable",
]
.iter()
.cloned()
.copied()
.map(String::from)
.collect();
static ref HTML_ATTRS: Vec<String> = HIGHLIGHT_NAMES
.iter()
.map(|s| format!("class={}", s))
.map(|s| format!("class={s}"))
.collect();
}
@ -492,16 +492,16 @@ fn test_highlighting_via_c_api() {
];
let highlight_names = highlights
.iter()
.map(|h| h["class=".len()..].as_ptr() as *const c_char)
.map(|h| h["class=".len()..].as_ptr().cast::<c_char>())
.collect::<Vec<_>>();
let highlight_attrs = highlights
.iter()
.map(|h| h.as_bytes().as_ptr() as *const c_char)
.map(|h| h.as_bytes().as_ptr().cast::<c_char>())
.collect::<Vec<_>>();
let highlighter = unsafe {
c::ts_highlighter_new(
&highlight_names[0] as *const *const c_char,
&highlight_attrs[0] as *const *const c_char,
std::ptr::addr_of!(highlight_names[0]),
std::ptr::addr_of!(highlight_attrs[0]),
highlights.len() as u32,
)
};
@ -523,9 +523,9 @@ fn test_highlighting_via_c_api() {
js_scope.as_ptr(),
js_injection_regex.as_ptr(),
language,
highlights_query.as_ptr() as *const c_char,
injections_query.as_ptr() as *const c_char,
locals_query.as_ptr() as *const c_char,
highlights_query.as_ptr().cast::<c_char>(),
injections_query.as_ptr().cast::<c_char>(),
locals_query.as_ptr().cast::<c_char>(),
highlights_query.len() as u32,
injections_query.len() as u32,
locals_query.len() as u32,
@ -547,8 +547,8 @@ fn test_highlighting_via_c_api() {
html_scope.as_ptr(),
html_injection_regex.as_ptr(),
language,
highlights_query.as_ptr() as *const c_char,
injections_query.as_ptr() as *const c_char,
highlights_query.as_ptr().cast::<c_char>(),
injections_query.as_ptr().cast::<c_char>(),
ptr::null(),
highlights_query.len() as u32,
injections_query.len() as u32,
@ -584,8 +584,7 @@ fn test_highlighting_via_c_api() {
let line_start = output_line_offsets[i] as usize;
let line_end = output_line_offsets
.get(i + 1)
.map(|x| *x as usize)
.unwrap_or(output_bytes.len());
.map_or(output_bytes.len(), |x| *x as usize);
lines.push(str::from_utf8(&output_bytes[line_start..line_end]).unwrap());
}
@ -718,9 +717,13 @@ fn to_html<'a>(
renderer
.render(events, src, &|highlight| HTML_ATTRS[highlight.0].as_bytes())
.unwrap();
Ok(renderer.lines().map(|s| s.to_string()).collect())
Ok(renderer
.lines()
.map(std::string::ToString::to_string)
.collect())
}
#[allow(clippy::type_complexity)]
fn to_token_vector<'a>(
src: &'a str,
language_config: &'a HighlightConfiguration,

View file

@ -6,7 +6,7 @@ use crate::parse::perform_edit;
use std::fs;
use tree_sitter::{Node, Parser, Point, Tree};
const JSON_EXAMPLE: &'static str = r#"
const JSON_EXAMPLE: &str = r#"
[
123,
@ -17,7 +17,7 @@ const JSON_EXAMPLE: &'static str = r#"
]
"#;
const GRAMMAR_WITH_ALIASES_AND_EXTRAS: &'static str = r#"{
const GRAMMAR_WITH_ALIASES_AND_EXTRAS: &str = r#"{
"name": "aliases_and_extras",
"extras": [
@ -60,8 +60,8 @@ fn test_node_child() {
assert_eq!(array_node.kind(), "array");
assert_eq!(array_node.named_child_count(), 3);
assert_eq!(array_node.start_byte(), JSON_EXAMPLE.find("[").unwrap());
assert_eq!(array_node.end_byte(), JSON_EXAMPLE.find("]").unwrap() + 1);
assert_eq!(array_node.start_byte(), JSON_EXAMPLE.find('[').unwrap());
assert_eq!(array_node.end_byte(), JSON_EXAMPLE.find(']').unwrap() + 1);
assert_eq!(array_node.start_position(), Point::new(2, 0));
assert_eq!(array_node.end_position(), Point::new(8, 1));
assert_eq!(array_node.child_count(), 7);
@ -82,13 +82,13 @@ fn test_node_child() {
assert_eq!(object_node.kind(), "object");
assert_eq!(right_bracket_node.kind(), "]");
assert_eq!(left_bracket_node.is_named(), false);
assert_eq!(number_node.is_named(), true);
assert_eq!(comma_node1.is_named(), false);
assert_eq!(false_node.is_named(), true);
assert_eq!(comma_node2.is_named(), false);
assert_eq!(object_node.is_named(), true);
assert_eq!(right_bracket_node.is_named(), false);
assert!(!left_bracket_node.is_named());
assert!(number_node.is_named());
assert!(!comma_node1.is_named());
assert!(false_node.is_named());
assert!(!comma_node2.is_named());
assert!(object_node.is_named());
assert!(!right_bracket_node.is_named());
assert_eq!(number_node.start_byte(), JSON_EXAMPLE.find("123").unwrap());
assert_eq!(
@ -106,7 +106,7 @@ fn test_node_child() {
assert_eq!(false_node.start_position(), Point::new(4, 2));
assert_eq!(false_node.end_position(), Point::new(4, 7));
assert_eq!(object_node.start_byte(), JSON_EXAMPLE.find("{").unwrap());
assert_eq!(object_node.start_byte(), JSON_EXAMPLE.find('{').unwrap());
assert_eq!(object_node.start_position(), Point::new(5, 2));
assert_eq!(object_node.end_position(), Point::new(7, 3));
@ -119,9 +119,9 @@ fn test_node_child() {
assert_eq!(pair_node.kind(), "pair");
assert_eq!(right_brace_node.kind(), "}");
assert_eq!(left_brace_node.is_named(), false);
assert_eq!(pair_node.is_named(), true);
assert_eq!(right_brace_node.is_named(), false);
assert!(!left_brace_node.is_named());
assert!(pair_node.is_named());
assert!(!right_brace_node.is_named());
assert_eq!(pair_node.start_byte(), JSON_EXAMPLE.find("\"x\"").unwrap());
assert_eq!(pair_node.end_byte(), JSON_EXAMPLE.find("null").unwrap() + 4);
@ -137,9 +137,9 @@ fn test_node_child() {
assert_eq!(colon_node.kind(), ":");
assert_eq!(null_node.kind(), "null");
assert_eq!(string_node.is_named(), true);
assert_eq!(colon_node.is_named(), false);
assert_eq!(null_node.is_named(), true);
assert!(string_node.is_named());
assert!(!colon_node.is_named());
assert!(null_node.is_named());
assert_eq!(
string_node.start_byte(),
@ -321,7 +321,7 @@ fn test_node_named_child() {
assert_eq!(false_node.end_position(), Point::new(4, 7));
assert_eq!(object_node.kind(), "object");
assert_eq!(object_node.start_byte(), JSON_EXAMPLE.find("{").unwrap());
assert_eq!(object_node.start_byte(), JSON_EXAMPLE.find('{').unwrap());
assert_eq!(object_node.start_position(), Point::new(5, 2));
assert_eq!(object_node.end_position(), Point::new(7, 3));
@ -435,7 +435,7 @@ fn test_node_descendant_for_range() {
let array_node = tree.root_node();
// Leaf node exactly matches the given bounds - byte query
let colon_index = JSON_EXAMPLE.find(":").unwrap();
let colon_index = JSON_EXAMPLE.find(':').unwrap();
let colon_node = array_node
.descendant_for_byte_range(colon_index, colon_index + 1)
.unwrap();
@ -456,7 +456,7 @@ fn test_node_descendant_for_range() {
assert_eq!(colon_node.end_position(), Point::new(6, 8));
// The given point is between two adjacent leaf nodes - byte query
let colon_index = JSON_EXAMPLE.find(":").unwrap();
let colon_index = JSON_EXAMPLE.find(':').unwrap();
let colon_node = array_node
.descendant_for_byte_range(colon_index, colon_index)
.unwrap();
@ -550,10 +550,10 @@ fn test_node_edit() {
for _ in 0..10 {
let mut nodes_before = get_all_nodes(&tree);
let edit = get_random_edit(&mut rand, &mut code);
let edit = get_random_edit(&mut rand, &code);
let mut tree2 = tree.clone();
let edit = perform_edit(&mut tree2, &mut code, &edit).unwrap();
for node in nodes_before.iter_mut() {
for node in &mut nodes_before {
node.edit(&edit);
}
@ -788,7 +788,7 @@ fn test_node_field_calls_in_language_without_fields() {
let mut cursor = root_node.walk();
assert_eq!(cursor.field_name(), None);
assert_eq!(cursor.goto_first_child(), true);
assert!(cursor.goto_first_child());
assert_eq!(cursor.field_name(), None);
}
@ -796,7 +796,7 @@ fn test_node_field_calls_in_language_without_fields() {
fn test_node_is_named_but_aliased_as_anonymous() {
let (parser_name, parser_code) = generate_parser_for_grammar(
&fs::read_to_string(
&fixtures_dir()
fixtures_dir()
.join("test_grammars")
.join("named_rule_aliased_as_anonymous")
.join("grammar.json"),
@ -890,15 +890,13 @@ fn get_all_nodes(tree: &Tree) -> Vec<Node> {
if !cursor.goto_first_child() {
visited_children = true;
}
} else {
if cursor.goto_next_sibling() {
visited_children = false;
} else if !cursor.goto_parent() {
break;
}
} else if cursor.goto_next_sibling() {
visited_children = false;
} else if !cursor.goto_parent() {
break;
}
}
return result;
result
}
fn parse_json_example() -> Tree {

View file

@ -34,7 +34,7 @@ fn test_grammar_that_should_hang_and_not_segfault() {
eprintln!(" {test_name}");
let tests_exec_path = std::env::args()
.nth(0)
.next()
.expect("Failed get get tests executable path");
match std::env::var(test_var) {

View file

@ -105,8 +105,7 @@ fn test_parsing_with_debug_graph_enabled() {
for line in log_reader {
assert!(
!has_zero_indexed_row(&line),
"Graph log output includes zero-indexed row: {}",
line
"Graph log output includes zero-indexed row: {line}",
);
}
}
@ -688,14 +687,10 @@ fn test_parsing_with_a_timeout() {
parser.set_timeout_micros(0);
let tree = parser
.parse_with(
&mut |offset, _| {
if offset > 5000 {
"".as_bytes()
} else if offset == 5000 {
"]".as_bytes()
} else {
",0".as_bytes()
}
&mut |offset, _| match offset {
5001.. => "".as_bytes(),
5000 => "]".as_bytes(),
_ => ",0".as_bytes(),
},
None,
)
@ -1019,7 +1014,11 @@ fn test_parsing_error_in_invalid_included_ranges() {
#[test]
fn test_parsing_utf16_code_with_errors_at_the_end_of_an_included_range() {
let source_code = "<script>a.</script>";
let utf16_source_code: Vec<u16> = source_code.as_bytes().iter().map(|c| *c as u16).collect();
let utf16_source_code: Vec<u16> = source_code
.as_bytes()
.iter()
.map(|c| u16::from(*c))
.collect();
let start_byte = 2 * source_code.find("a.").unwrap();
let end_byte = 2 * source_code.find("</script>").unwrap();
@ -1382,7 +1381,7 @@ fn test_grammars_that_can_hang_on_eof() {
parser.parse("\"", None).unwrap();
}
fn simple_range(start: usize, end: usize) -> Range {
const fn simple_range(start: usize, end: usize) -> Range {
Range {
start_byte: start,
end_byte: end,

View file

@ -81,7 +81,7 @@ pub fn test_with_seed(args: TokenStream, input: TokenStream) -> TokenStream {
retry.replace(LitInt::new("0", Span::mixed_site()));
}
Ok(Args {
Ok(Self {
retry: retry.expect("`retry` parameter is required"),
seed: seed.expect("`seed` parameter is required"),
seed_fn,
@ -101,8 +101,6 @@ pub fn test_with_seed(args: TokenStream, input: TokenStream) -> TokenStream {
let attrs = func.attrs.clone();
let name = func.sig.ident.clone();
// dbg!(quote::ToTokens::into_token_stream(&func));
TokenStream::from(quote! {
#[test]
#(#attrs),*

View file

@ -84,14 +84,14 @@ fn test_query_errors_on_invalid_syntax() {
.message,
[
r#"(identifier) "h "#, //
r#" ^"#,
r" ^",
]
.join("\n")
);
// 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,37 +127,37 @@ 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,
[
r#"((identifier) @x (#eq? @x a"#,
r#" ^"#,
r"((identifier) @x (#eq? @x a",
r" ^",
]
.join("\n")
);
// 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,
[
//
r#"(statement_block .)"#,
r#" ^"#
r"(statement_block .)",
r" ^"
]
.join("\n")
);
// 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,
[
r#"(statement_block ! (if_statement))"#,
r#" ^"#
r"(statement_block ! (if_statement))",
r" ^"
]
.join("\n")
);
@ -170,7 +170,7 @@ fn test_query_errors_on_invalid_syntax() {
.message,
[
r#"(parameter_list [ ")" @foo)"#,
r#" ^"#
r" ^"
]
.join("\n")
);
@ -180,13 +180,13 @@ fn test_query_errors_on_invalid_syntax() {
assert_eq!(
Query::new(
&get_language("python"),
r#"[(unary_operator (_) @operand) (not_operator (_) @operand]"#
r"[(unary_operator (_) @operand) (not_operator (_) @operand]"
)
.unwrap_err()
.message,
[
r#"[(unary_operator (_) @operand) (not_operator (_) @operand]"#,
r#" ^"#
r"[(unary_operator (_) @operand) (not_operator (_) @operand]",
r" ^"
]
.join("\n")
);
@ -1143,9 +1143,9 @@ fn test_query_matches_with_optional_nodes_inside_of_repetitions() {
assert_query_matches(
&language,
&query,
r#"
r"
var a = [1, 2, 3, 4]
"#,
",
&[(
0,
vec![("num", "1"), ("num", "2"), ("num", "3"), ("num", "4")],
@ -1160,16 +1160,16 @@ fn test_query_matches_with_top_level_repetitions() {
let language = get_language("javascript");
let query = Query::new(
&language,
r#"
r"
(comment)+ @doc
"#,
",
)
.unwrap();
assert_query_matches(
&language,
&query,
r#"
r"
// a
// b
// c
@ -1177,7 +1177,7 @@ fn test_query_matches_with_top_level_repetitions() {
d()
// e
"#,
",
&[
(0, vec![("doc", "// a"), ("doc", "// b"), ("doc", "// c")]),
(0, vec![("doc", "// e")]),
@ -1195,7 +1195,7 @@ fn test_query_matches_with_non_terminal_repetitions_within_root() {
assert_query_matches(
&language,
&query,
r#"
r"
function f() {
d;
e;
@ -1205,7 +1205,7 @@ fn test_query_matches_with_non_terminal_repetitions_within_root() {
a;
b;
c;
"#,
",
&[
(0, vec![("id", "d"), ("id", "e"), ("id", "f"), ("id", "g")]),
(0, vec![("id", "a"), ("id", "b"), ("id", "c")]),
@ -1230,13 +1230,13 @@ fn test_query_matches_with_nested_repetitions() {
assert_query_matches(
&language,
&query,
r#"
r"
var a = b, c, d
var e, f
// more
var g
"#,
",
&[
(
0,
@ -1257,7 +1257,7 @@ fn test_query_matches_with_multiple_repetition_patterns_that_intersect_other_pat
// matches: up to two for each pattern that begins with a comment.
let query = Query::new(
&language,
r#"
r"
(call_expression
function: (member_expression
property: (property_identifier) @name)) @ref.method
@ -1270,7 +1270,7 @@ fn test_query_matches_with_multiple_repetition_patterns_that_intersect_other_pat
((comment)* @doc (method_definition))
(comment) @comment
"#,
",
)
.unwrap();
@ -1441,11 +1441,11 @@ fn test_query_matches_with_nested_optional_nodes() {
assert_query_matches(
&language,
&query,
r#"
r"
a(b, c(), d(null, 1, 2))
e()
f(g())
"#,
",
&[
(0, vec![("outer-fn", "a"), ("inner-fn", "c")]),
(0, vec![("outer-fn", "c")]),
@ -1487,7 +1487,7 @@ fn test_query_matches_with_repeated_internal_nodes() {
",
&[(0, vec![("deco", "c"), ("deco", "d"), ("name", "e")])],
);
})
});
}
#[test]
@ -1526,7 +1526,7 @@ fn test_query_matches_with_simple_alternatives() {
(0, vec![("key", "'l'"), ("val1", "function m() {}")]),
],
);
})
});
}
#[test]
@ -1562,7 +1562,7 @@ fn test_query_matches_with_alternatives_in_repetitions() {
),
],
);
})
});
}
#[test]
@ -1603,7 +1603,7 @@ fn test_query_matches_with_alternatives_at_root() {
(0, vec![("keyword", "throw")]),
],
);
})
});
}
#[test]
@ -1612,13 +1612,13 @@ fn test_query_matches_with_alternatives_under_fields() {
let language = get_language("javascript");
let query = Query::new(
&language,
r#"
r"
(assignment_expression
left: [
(identifier) @variable
(member_expression property: (property_identifier) @variable)
])
"#,
",
)
.unwrap();
@ -1840,7 +1840,7 @@ fn test_repetitions_before_with_alternatives() {
let language = get_language("rust");
let query = Query::new(
&language,
r#"
r"
(
(line_comment)* @comment
.
@ -1851,14 +1851,14 @@ fn test_repetitions_before_with_alternatives() {
(impl_item type: (_) @name)
]
)
"#,
",
)
.unwrap();
assert_query_matches(
&language,
&query,
r#"
r"
// a
// b
fn c() {}
@ -1866,7 +1866,7 @@ fn test_repetitions_before_with_alternatives() {
// d
// e
impl F {}
"#,
",
&[
(
0,
@ -1915,7 +1915,7 @@ fn test_query_matches_with_supertypes() {
let language = get_language("python");
let query = Query::new(
&language,
r#"
r"
(argument_list (expression) @arg)
(keyword_argument
@ -1925,7 +1925,7 @@ fn test_query_matches_with_supertypes() {
left: (identifier) @var_def)
(primary_expression/identifier) @var_ref
"#,
",
)
.unwrap();
@ -1952,6 +1952,7 @@ fn test_query_matches_with_supertypes() {
}
#[test]
#[allow(clippy::reversed_empty_ranges)]
fn test_query_matches_within_byte_range() {
allocations::record(|| {
let language = get_language("javascript");
@ -2627,7 +2628,7 @@ fn test_query_matches_with_captured_wildcard_at_root() {
vec![("stmt", "try_statement", 7), ("block", "block", 12)],
vec![("stmt", "while_statement", 1), ("block", "block", 14)],
]
)
);
});
}
@ -2637,10 +2638,10 @@ fn test_query_matches_with_no_captures() {
let language = get_language("javascript");
let query = Query::new(
&language,
r#"
r"
(identifier)
(string) @s
"#,
",
)
.unwrap();
@ -2980,7 +2981,7 @@ fn test_query_captures_with_predicates() {
let query = Query::new(
&language,
r#"
r"
((call_expression (identifier) @foo)
(#set! name something)
(#set! cool)
@ -2988,7 +2989,7 @@ fn test_query_captures_with_predicates() {
((property_identifier) @bar
(#is? cool)
(#is-not? name something))"#,
(#is-not? name something))",
)
.unwrap();
@ -3075,13 +3076,13 @@ fn test_query_captures_with_duplicates() {
let language = get_language("javascript");
let query = Query::new(
&language,
r#"
r"
(variable_declarator
name: (identifier) @function
value: (function_expression))
(identifier) @variable
"#,
",
)
.unwrap();
@ -3129,7 +3130,7 @@ fn test_query_captures_with_many_nested_results_without_fields() {
let method_count = 50;
let mut source = "x = { y: {\n".to_owned();
for i in 0..method_count {
writeln!(&mut source, " method{}: $ => null,", i).unwrap();
writeln!(&mut source, " method{i}: $ => null,").unwrap();
}
source.push_str("}};\n");
@ -3173,14 +3174,14 @@ fn test_query_captures_with_many_nested_results_with_fields() {
// Search expressions like `a ? a.b : null`
let query = Query::new(
&language,
r#"
r"
((ternary_expression
condition: (identifier) @left
consequence: (member_expression
object: (identifier) @right)
alternative: (null))
(#eq? @left @right))
"#,
",
)
.unwrap();
@ -3189,7 +3190,7 @@ fn test_query_captures_with_many_nested_results_with_fields() {
let count = 50;
let mut source = "a ? {".to_owned();
for i in 0..count {
writeln!(&mut source, " x: y{} ? y{}.z : null,", i, i).unwrap();
writeln!(&mut source, " x: y{i} ? y{i}.z : null,").unwrap();
}
source.push_str("} : null;\n");
@ -3254,7 +3255,7 @@ fn test_query_captures_with_too_many_nested_results() {
// be buffered, in order to prevent captures from being returned out-of-order.
let query = Query::new(
&language,
r#"
r"
;; easy 👇
(call_expression
function: (member_expression
@ -3265,7 +3266,7 @@ fn test_query_captures_with_too_many_nested_results() {
function: (member_expression
property: (property_identifier) @template-tag)
arguments: (template_string)) @template-call
"#,
",
)
.unwrap();
@ -3362,11 +3363,10 @@ fn test_query_captures_with_definite_pattern_containing_many_nested_matches() {
let captures = cursor.captures(&query, tree.root_node(), source.as_bytes());
assert_eq!(
collect_captures(captures, &query, source),
[("l-bracket", "[")]
.iter()
std::iter::once(&("l-bracket", "["))
.chain([("dot", "."); 40].iter())
.chain([("r-bracket", "]")].iter())
.cloned()
.chain(std::iter::once(&("r-bracket", "]")))
.copied()
.collect::<Vec<_>>(),
);
});
@ -3378,11 +3378,11 @@ fn test_query_captures_ordered_by_both_start_and_end_positions() {
let language = get_language("javascript");
let query = Query::new(
&language,
r#"
r"
(call_expression) @call
(member_expression) @member
(identifier) @variable
"#,
",
)
.unwrap();
@ -3418,12 +3418,12 @@ fn test_query_captures_with_matches_removed() {
let language = get_language("javascript");
let query = Query::new(
&language,
r#"
r"
(binary_expression
left: (identifier) @left
operator: _ @op
right: (identifier) @right)
"#,
",
)
.unwrap();
@ -3504,9 +3504,9 @@ fn test_query_captures_and_matches_iterators_are_fused() {
let language = get_language("javascript");
let query = Query::new(
&language,
r#"
r"
(comment) @comment
"#,
",
)
.unwrap();
@ -3685,7 +3685,7 @@ fn test_query_capture_names() {
#[test]
fn test_query_lifetime_is_separate_from_nodes_lifetime() {
allocations::record(|| {
let query = r#"(call_expression) @call"#;
let query = r"(call_expression) @call";
let source = "a(1); b(2);";
let language = get_language("javascript");
@ -3926,7 +3926,7 @@ fn test_query_is_pattern_guaranteed_at_step() {
Row {
description: "no guaranteed steps",
language: get_language("python"),
pattern: r#"(expression_statement (string))"#,
pattern: r"(expression_statement (string))",
results_by_substring: &[("expression_statement", false), ("string", false)],
},
Row {
@ -4004,7 +4004,7 @@ fn test_query_is_pattern_guaranteed_at_step() {
Row {
description: "a guaranteed step with a field",
language: get_language("javascript"),
pattern: r#"(binary_expression left: (expression) right: (_))"#,
pattern: r"(binary_expression left: (expression) right: (_))",
results_by_substring: &[
("binary_expression", false),
("(expression)", false),
@ -4014,7 +4014,7 @@ fn test_query_is_pattern_guaranteed_at_step() {
Row {
description: "multiple guaranteed steps with fields",
language: get_language("javascript"),
pattern: r#"(function_declaration name: (identifier) body: (statement_block))"#,
pattern: r"(function_declaration name: (identifier) body: (statement_block))",
results_by_substring: &[
("function_declaration", false),
("identifier", true),
@ -4054,12 +4054,12 @@ fn test_query_is_pattern_guaranteed_at_step() {
Row {
description: "nesting, no guaranteed steps",
language: get_language("javascript"),
pattern: r#"
pattern: r"
(call_expression
function: (member_expression
property: (property_identifier) @template-tag)
arguments: (template_string)) @template-call
"#,
",
results_by_substring: &[("property_identifier", false), ("template_string", false)],
},
Row {
@ -4098,15 +4098,15 @@ fn test_query_is_pattern_guaranteed_at_step() {
Row {
description: "alternation where one branch has guaranteed steps",
language: get_language("javascript"),
pattern: r#"
pattern: r"
[
(unary_expression (identifier))
(call_expression
function: (_)
arguments: (_))
(binary_expression right:(call_expression))
(binary_expression right: (call_expression))
]
"#,
",
results_by_substring: &[
("identifier", false),
("right:", false),
@ -4151,19 +4151,19 @@ fn test_query_is_pattern_guaranteed_at_step() {
Row {
description: "hidden nodes that have several fields",
language: get_language("java"),
pattern: r#"
pattern: r"
(method_declaration name: (identifier))
"#,
",
results_by_substring: &[("name:", true)],
},
Row {
description: "top-level non-terminal extra nodes",
language: get_language("ruby"),
pattern: r#"
pattern: r"
(heredoc_body
(interpolation)
(heredoc_end) @end)
"#,
",
results_by_substring: &[
("(heredoc_body", false),
("(interpolation)", false),
@ -4173,12 +4173,12 @@ fn test_query_is_pattern_guaranteed_at_step() {
Row {
description: "multiple extra nodes",
language: get_language("rust"),
pattern: r#"
pattern: r"
(call_expression
(line_comment) @a
(line_comment) @b
(arguments))
"#,
",
results_by_substring: &[
("(line_comment) @a", false),
("(line_comment) @b", false),
@ -4190,7 +4190,7 @@ fn test_query_is_pattern_guaranteed_at_step() {
allocations::record(|| {
eprintln!();
for row in rows.iter() {
for row in rows {
if let Some(filter) = EXAMPLE_FILTER.as_ref() {
if !row.description.contains(filter.as_str()) {
continue;
@ -4211,7 +4211,7 @@ fn test_query_is_pattern_guaranteed_at_step() {
.join(" "),
substring,
is_definite,
)
);
}
}
});
@ -4228,12 +4228,12 @@ fn test_query_is_pattern_rooted() {
let rows = [
Row {
description: "simple token",
pattern: r#"(identifier)"#,
pattern: r"(identifier)",
is_rooted: true,
},
Row {
description: "simple non-terminal",
pattern: r#"(function_definition name: (identifier))"#,
pattern: r"(function_definition name: (identifier))",
is_rooted: true,
},
Row {
@ -4243,11 +4243,11 @@ fn test_query_is_pattern_rooted() {
},
Row {
description: "alternative of many non-terminals",
pattern: r#"[
pattern: r"[
(function_definition name: (identifier))
(class_definition name: (identifier))
(block)
]"#,
]",
is_rooted: true,
},
Row {
@ -4257,7 +4257,7 @@ fn test_query_is_pattern_rooted() {
},
Row {
description: "top-level repetition",
pattern: r#"(comment)*"#,
pattern: r"(comment)*",
is_rooted: false,
},
Row {
@ -4272,12 +4272,12 @@ fn test_query_is_pattern_rooted() {
},
Row {
description: "alternative where one option has a top-level repetition",
pattern: r#"[
pattern: r"[
(block)
(class_definition)
(comment)*
(function_definition)
]"#,
]",
is_rooted: false,
},
];
@ -4303,7 +4303,7 @@ fn test_query_is_pattern_rooted() {
.split_ascii_whitespace()
.collect::<Vec<_>>()
.join(" "),
)
);
}
});
}
@ -4320,25 +4320,25 @@ fn test_query_is_pattern_non_local() {
let rows = [
Row {
description: "simple token",
pattern: r#"(identifier)"#,
pattern: r"(identifier)",
language: get_language("python"),
is_non_local: false,
},
Row {
description: "siblings that can occur in an argument list",
pattern: r#"((identifier) (identifier))"#,
pattern: r"((identifier) (identifier))",
language: get_language("python"),
is_non_local: true,
},
Row {
description: "siblings that can occur in a statement block",
pattern: r#"((return_statement) (return_statement))"#,
pattern: r"((return_statement) (return_statement))",
language: get_language("python"),
is_non_local: true,
},
Row {
description: "siblings that can occur in a source file",
pattern: r#"((function_definition) (class_definition))"#,
pattern: r"((function_definition) (class_definition))",
language: get_language("python"),
is_non_local: true,
},
@ -4356,25 +4356,25 @@ fn test_query_is_pattern_non_local() {
},
Row {
description: "siblings that can occur in a class body, wildcard root",
pattern: r#"(_ (method_definition) (method_definition)) @foo"#,
pattern: r"(_ (method_definition) (method_definition)) @foo",
language: get_language("javascript"),
is_non_local: true,
},
Row {
description: "top-level repetitions that can occur in a class body",
pattern: r#"(method_definition)+ @foo"#,
pattern: r"(method_definition)+ @foo",
language: get_language("javascript"),
is_non_local: true,
},
Row {
description: "top-level repetitions that can occur in a statement block",
pattern: r#"(return_statement)+ @foo"#,
pattern: r"(return_statement)+ @foo",
language: get_language("javascript"),
is_non_local: true,
},
Row {
description: "rooted pattern that can occur in a statement block",
pattern: r#"(return_statement) @foo"#,
pattern: r"(return_statement) @foo",
language: get_language("javascript"),
is_non_local: false,
},
@ -4400,7 +4400,7 @@ fn test_query_is_pattern_non_local() {
.split_ascii_whitespace()
.collect::<Vec<_>>()
.join(" "),
)
);
}
});
}
@ -4419,17 +4419,17 @@ fn test_capture_quantifiers() {
Row {
description: "Top level capture",
language: get_language("python"),
pattern: r#"
pattern: r"
(module) @mod
"#,
",
capture_quantifiers: &[(0, "mod", CaptureQuantifier::One)],
},
Row {
description: "Nested list capture capture",
language: get_language("javascript"),
pattern: r#"
pattern: r"
(array (_)* @elems) @array
"#,
",
capture_quantifiers: &[
(0, "array", CaptureQuantifier::One),
(0, "elems", CaptureQuantifier::ZeroOrMore),
@ -4438,9 +4438,9 @@ fn test_capture_quantifiers() {
Row {
description: "Nested non-empty list capture capture",
language: get_language("javascript"),
pattern: r#"
pattern: r"
(array (_)+ @elems) @array
"#,
",
capture_quantifiers: &[
(0, "array", CaptureQuantifier::One),
(0, "elems", CaptureQuantifier::OneOrMore),
@ -4450,9 +4450,9 @@ fn test_capture_quantifiers() {
Row {
description: "capture nested in optional pattern",
language: get_language("javascript"),
pattern: r#"
pattern: r"
(array (call_expression (arguments (_) @arg))? @call) @array
"#,
",
capture_quantifiers: &[
(0, "array", CaptureQuantifier::One),
(0, "call", CaptureQuantifier::ZeroOrOne),
@ -4462,9 +4462,9 @@ fn test_capture_quantifiers() {
Row {
description: "optional capture nested in non-empty list pattern",
language: get_language("javascript"),
pattern: r#"
pattern: r"
(array (call_expression (arguments (_)? @arg))+ @call) @array
"#,
",
capture_quantifiers: &[
(0, "array", CaptureQuantifier::One),
(0, "call", CaptureQuantifier::OneOrMore),
@ -4474,9 +4474,9 @@ fn test_capture_quantifiers() {
Row {
description: "non-empty list capture nested in optional pattern",
language: get_language("javascript"),
pattern: r#"
pattern: r"
(array (call_expression (arguments (_)+ @args))? @call) @array
"#,
",
capture_quantifiers: &[
(0, "array", CaptureQuantifier::One),
(0, "call", CaptureQuantifier::ZeroOrOne),
@ -4487,19 +4487,19 @@ fn test_capture_quantifiers() {
Row {
description: "capture is the same in all alternatives",
language: get_language("javascript"),
pattern: r#"[
pattern: r"[
(function_declaration name:(identifier) @name)
(call_expression function:(identifier) @name)
]"#,
]",
capture_quantifiers: &[(0, "name", CaptureQuantifier::One)],
},
Row {
description: "capture appears in some alternatives",
language: get_language("javascript"),
pattern: r#"[
pattern: r"[
(function_declaration name:(identifier) @name)
(function_expression)
] @fun"#,
] @fun",
capture_quantifiers: &[
(0, "fun", CaptureQuantifier::One),
(0, "name", CaptureQuantifier::ZeroOrOne),
@ -4508,10 +4508,10 @@ fn test_capture_quantifiers() {
Row {
description: "capture has different quantifiers in alternatives",
language: get_language("javascript"),
pattern: r#"[
(call_expression arguments:(arguments (_)+ @args))
(new_expression arguments:(arguments (_)? @args))
] @call"#,
pattern: r"[
(call_expression arguments: (arguments (_)+ @args))
(new_expression arguments: (arguments (_)? @args))
] @call",
capture_quantifiers: &[
(0, "call", CaptureQuantifier::One),
(0, "args", CaptureQuantifier::ZeroOrMore),
@ -4521,9 +4521,9 @@ fn test_capture_quantifiers() {
Row {
description: "siblings have different captures with different quantifiers",
language: get_language("javascript"),
pattern: r#"
pattern: r"
(call_expression (arguments (identifier)? @self (_)* @args)) @call
"#,
",
capture_quantifiers: &[
(0, "call", CaptureQuantifier::One),
(0, "self", CaptureQuantifier::ZeroOrOne),
@ -4533,9 +4533,9 @@ fn test_capture_quantifiers() {
Row {
description: "siblings have same capture with different quantifiers",
language: get_language("javascript"),
pattern: r#"
pattern: r"
(call_expression (arguments (identifier) @args (_)* @args)) @call
"#,
",
capture_quantifiers: &[
(0, "call", CaptureQuantifier::One),
(0, "args", CaptureQuantifier::OneOrMore),
@ -4545,7 +4545,7 @@ fn test_capture_quantifiers() {
Row {
description: "combined nesting, alternatives, and siblings",
language: get_language("javascript"),
pattern: r#"
pattern: r"
(array
(call_expression
(arguments [
@ -4554,7 +4554,7 @@ fn test_capture_quantifiers() {
])
)+ @call
) @array
"#,
",
capture_quantifiers: &[
(0, "array", CaptureQuantifier::One),
(0, "call", CaptureQuantifier::OneOrMore),
@ -4566,12 +4566,12 @@ fn test_capture_quantifiers() {
Row {
description: "multiple patterns",
language: get_language("javascript"),
pattern: r#"
pattern: r"
(function_declaration name: (identifier) @x)
(statement_identifier) @y
(property_identifier)+ @z
(array (identifier)* @x)
"#,
",
capture_quantifiers: &[
// x
(0, "x", CaptureQuantifier::One),
@ -4593,7 +4593,7 @@ fn test_capture_quantifiers() {
Row {
description: "multiple alternatives",
language: get_language("javascript"),
pattern: r#"
pattern: r"
[
(array (identifier) @x)
(function_declaration name: (identifier)+ @x)
@ -4602,7 +4602,7 @@ fn test_capture_quantifiers() {
(array (identifier) @x)
(function_declaration name: (identifier)+ @x)
]
"#,
",
capture_quantifiers: &[
(0, "x", CaptureQuantifier::OneOrMore),
(1, "x", CaptureQuantifier::OneOrMore),
@ -4613,7 +4613,7 @@ fn test_capture_quantifiers() {
allocations::record(|| {
eprintln!();
for row in rows.iter() {
for row in rows {
if let Some(filter) = EXAMPLE_FILTER.as_ref() {
if !row.description.contains(filter.as_str()) {
continue;
@ -4636,7 +4636,7 @@ fn test_capture_quantifiers() {
capture,
*expected_quantifier,
actual_quantifier,
)
);
}
}
});
@ -4750,9 +4750,9 @@ fn test_query_max_start_depth() {
Row {
description: "depth 0: match translation unit",
depth: 0,
pattern: r#"
pattern: r"
(translation_unit) @capture
"#,
",
matches: &[
(0, &[("capture", "if (a1 && a2) {\n if (b1 && b2) { }\n if (c) { }\n}\nif (d) {\n if (e1 && e2) { }\n if (f) { }\n}\n")]),
]
@ -4760,17 +4760,17 @@ fn test_query_max_start_depth() {
Row {
description: "depth 0: match none",
depth: 0,
pattern: r#"
pattern: r"
(if_statement) @capture
"#,
",
matches: &[]
},
Row {
description: "depth 1: match 2 if statements at the top level",
depth: 1,
pattern: r#"
pattern: r"
(if_statement) @capture
"#,
",
matches : &[
(0, &[("capture", "if (a1 && a2) {\n if (b1 && b2) { }\n if (c) { }\n}")]),
(0, &[("capture", "if (d) {\n if (e1 && e2) { }\n if (f) { }\n}")]),
@ -4779,13 +4779,13 @@ fn test_query_max_start_depth() {
Row {
description: "depth 1 with deep pattern: match the only the first if statement",
depth: 1,
pattern: r#"
pattern: r"
(if_statement
condition: (parenthesized_expression
(binary_expression)
)
) @capture
"#,
",
matches: &[
(0, &[("capture", "if (a1 && a2) {\n if (b1 && b2) { }\n if (c) { }\n}")]),
]
@ -4793,13 +4793,13 @@ fn test_query_max_start_depth() {
Row {
description: "depth 3 with deep pattern: match all if statements with a binexpr condition",
depth: 3,
pattern: r#"
pattern: r"
(if_statement
condition: (parenthesized_expression
(binary_expression)
)
) @capture
"#,
",
matches: &[
(0, &[("capture", "if (a1 && a2) {\n if (b1 && b2) { }\n if (c) { }\n}")]),
(0, &[("capture", "if (b1 && b2) { }")]),
@ -4815,7 +4815,7 @@ fn test_query_max_start_depth() {
let tree = parser.parse(source, None).unwrap();
let mut cursor = QueryCursor::new();
for row in rows.iter() {
for row in rows {
eprintln!(" query example: {:?}", row.description);
let query = Query::new(&language, row.pattern).unwrap();
@ -4950,7 +4950,7 @@ fn test_query_max_start_depth_more() {
let node = matches.next().unwrap().captures[0].node;
assert_eq!(node.kind(), "compound_statement");
for row in rows.iter() {
for row in rows {
eprintln!(" depth: {}", row.depth);
cursor.set_max_start_depth(Some(row.depth));

View file

@ -68,7 +68,7 @@ const JS_TAG_QUERY: &str = r#"
function: (identifier) @name) @reference.call
"#;
const RUBY_TAG_QUERY: &str = r#"
const RUBY_TAG_QUERY: &str = r"
(method
name: (_) @name) @definition.method
@ -79,7 +79,7 @@ const RUBY_TAG_QUERY: &str = r#"
((identifier) @name @reference.call
(#is-not? local))
"#;
";
#[test]
fn test_tags_python() {
@ -132,7 +132,7 @@ fn test_tags_python() {
fn test_tags_javascript() {
let language = get_language("javascript");
let tags_config = TagsConfiguration::new(language, JS_TAG_QUERY, "").unwrap();
let source = br#"
let source = br"
// hi
// Data about a customer.
@ -150,7 +150,7 @@ fn test_tags_javascript() {
class Agent {
}
"#;
";
let mut tag_context = TagsContext::new();
let tags = tag_context
@ -305,10 +305,10 @@ fn test_tags_with_parse_error() {
let tags_config = TagsConfiguration::new(language, PYTHON_TAG_QUERY, "").unwrap();
let mut tag_context = TagsContext::new();
let source = br#"
let source = br"
class Fine: pass
class Bad
"#;
";
let (tags, failed) = tag_context
.generate_tags(&tags_config, source, None)
@ -391,7 +391,7 @@ fn test_tags_via_c_api() {
};
let docs = str::from_utf8(unsafe {
slice::from_raw_parts(
c::ts_tags_buffer_docs(buffer) as *const u8,
c::ts_tags_buffer_docs(buffer).cast::<u8>(),
c::ts_tags_buffer_docs_len(buffer) as usize,
)
})

View file

@ -55,5 +55,5 @@ fn test_tags_test_with_basic_test() {
"reference.call".to_string()
),
]
)
);
}

View file

@ -20,12 +20,12 @@ where
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());
assert_eq!("comment", tree.root_node().child(0).unwrap().kind());
(tree, language)
}
fn tree_query<I: AsRef<[u8]>>(tree: &Tree, text: impl TextProvider<I>, language: Language) {
let query = Query::new(&language, "((comment) @c (#eq? @c \"// comment\"))").unwrap();
fn tree_query<I: AsRef<[u8]>>(tree: &Tree, text: impl TextProvider<I>, language: &Language) {
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();
@ -39,7 +39,7 @@ fn check_parsing<I: AsRef<[u8]>>(
text_provider: impl TextProvider<I>,
) {
let (tree, language) = parse_text(parser_text);
tree_query(&tree, text_provider, language);
tree_query(&tree, text_provider, &language);
}
fn check_parsing_callback<T, F, I: AsRef<[u8]>>(
@ -50,7 +50,7 @@ fn check_parsing_callback<T, F, I: AsRef<[u8]>>(
F: FnMut(usize, Point) -> T,
{
let (tree, language) = parse_text_with(parser_callback);
tree_query(&tree, text_provider, language);
tree_query(&tree, text_provider, &language);
}
#[test]
@ -114,7 +114,7 @@ fn test_text_provider_callback_with_str_slice() {
check_parsing_callback(
&mut |offset, _point| {
(offset < text.len())
.then(|| text.as_bytes())
.then_some(text.as_bytes())
.unwrap_or_default()
},
|_node: Node<'_>| iter::once(text),
@ -128,7 +128,7 @@ fn test_text_provider_callback_with_owned_string_slice() {
check_parsing_callback(
&mut |offset, _point| {
(offset < text.len())
.then(|| text.as_bytes())
.then_some(text.as_bytes())
.unwrap_or_default()
},
|_node: Node<'_>| {
@ -145,7 +145,7 @@ fn test_text_provider_callback_with_owned_bytes_vec_slice() {
check_parsing_callback(
&mut |offset, _point| {
(offset < text.len())
.then(|| text.as_bytes())
.then_some(text.as_bytes())
.unwrap_or_default()
},
|_node: Node<'_>| {
@ -162,7 +162,7 @@ fn test_text_provider_callback_with_owned_arc_of_bytes_slice() {
check_parsing_callback(
&mut |offset, _point| {
(offset < text.len())
.then(|| text.as_bytes())
.then_some(text.as_bytes())
.unwrap_or_default()
},
|_node: Node<'_>| {

View file

@ -207,7 +207,7 @@ fn test_tree_edit() {
// replacement that starts in whitespace and extends beyond the end of the tree:
// shift the token's start position and empty out its content.
{
let mut tree = tree.clone();
let mut tree = tree;
tree.edit(&InputEdit {
start_byte: 6,
old_end_byte: 90,
@ -322,55 +322,55 @@ fn test_tree_cursor() {
assert!(cursor.goto_first_child());
assert_eq!(cursor.node().kind(), "struct");
assert_eq!(cursor.node().is_named(), false);
assert!(!cursor.node().is_named());
assert!(cursor.goto_next_sibling());
assert_eq!(cursor.node().kind(), "type_identifier");
assert_eq!(cursor.node().is_named(), true);
assert!(cursor.node().is_named());
assert!(cursor.goto_next_sibling());
assert_eq!(cursor.node().kind(), "field_declaration_list");
assert_eq!(cursor.node().is_named(), true);
assert!(cursor.node().is_named());
assert!(cursor.goto_last_child());
assert_eq!(cursor.node().kind(), "}");
assert_eq!(cursor.node().is_named(), false);
assert!(!cursor.node().is_named());
assert_eq!(cursor.node().start_position(), Point { row: 4, column: 16 });
assert!(cursor.goto_previous_sibling());
assert_eq!(cursor.node().kind(), ",");
assert_eq!(cursor.node().is_named(), false);
assert!(!cursor.node().is_named());
assert_eq!(cursor.node().start_position(), Point { row: 3, column: 32 });
assert!(cursor.goto_previous_sibling());
assert_eq!(cursor.node().kind(), "field_declaration");
assert_eq!(cursor.node().is_named(), true);
assert!(cursor.node().is_named());
assert_eq!(cursor.node().start_position(), Point { row: 3, column: 20 });
assert!(cursor.goto_previous_sibling());
assert_eq!(cursor.node().kind(), ",");
assert_eq!(cursor.node().is_named(), false);
assert!(!cursor.node().is_named());
assert_eq!(cursor.node().start_position(), Point { row: 2, column: 24 });
assert!(cursor.goto_previous_sibling());
assert_eq!(cursor.node().kind(), "field_declaration");
assert_eq!(cursor.node().is_named(), true);
assert!(cursor.node().is_named());
assert_eq!(cursor.node().start_position(), Point { row: 2, column: 20 });
assert!(cursor.goto_previous_sibling());
assert_eq!(cursor.node().kind(), "{");
assert_eq!(cursor.node().is_named(), false);
assert!(!cursor.node().is_named());
assert_eq!(cursor.node().start_position(), Point { row: 1, column: 29 });
let mut copy = tree.walk();
copy.reset_to(&cursor);
assert_eq!(copy.node().kind(), "{");
assert_eq!(copy.node().is_named(), false);
assert!(!copy.node().is_named());
assert!(copy.goto_parent());
assert_eq!(copy.node().kind(), "field_declaration_list");
assert_eq!(copy.node().is_named(), true);
assert!(copy.node().is_named());
assert!(copy.goto_parent());
assert_eq!(copy.node().kind(), "struct_item");
@ -596,11 +596,11 @@ fn test_get_changed_ranges() {
inserted_text: b"othing".to_vec(),
};
let inverse_edit = invert_edit(&source_code, &edit);
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, edit);
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, &edit);
assert_eq!(ranges, vec![range_of(&source_code, "nothing")]);
// Replace `nothing` with `null` - that token has changed syntax
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, inverse_edit);
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, &inverse_edit);
assert_eq!(ranges, vec![range_of(&source_code, "null")]);
}
@ -616,11 +616,11 @@ fn test_get_changed_ranges() {
inserted_text: b"\n".to_vec(),
};
let inverse_edit = invert_edit(&source_code, &edit);
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, edit);
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, &edit);
assert_eq!(ranges, vec![]);
// Remove leading newline - no changed ranges
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, inverse_edit);
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, &inverse_edit);
assert_eq!(ranges, vec![]);
}
@ -636,7 +636,7 @@ fn test_get_changed_ranges() {
inserted_text: b", b: false".to_vec(),
};
let inverse_edit1 = invert_edit(&source_code, &edit1);
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, edit1);
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, &edit1);
assert_eq!(ranges, vec![range_of(&source_code, ", b: false")]);
let edit2 = Edit {
@ -645,21 +645,21 @@ fn test_get_changed_ranges() {
inserted_text: b", c: 1".to_vec(),
};
let inverse_edit2 = invert_edit(&source_code, &edit2);
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, edit2);
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, &edit2);
assert_eq!(ranges, vec![range_of(&source_code, ", c: 1")]);
// Remove the middle pair
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, inverse_edit2);
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, &inverse_edit2);
assert_eq!(ranges, vec![]);
// Remove the second pair
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, inverse_edit1);
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, &inverse_edit1);
assert_eq!(ranges, vec![]);
}
// Wrapping elements in larger expressions
{
let mut tree = tree.clone();
let mut tree = tree;
let mut source_code = source_code.clone();
// Replace `null` with the binary expression `b === null`
@ -669,11 +669,11 @@ fn test_get_changed_ranges() {
inserted_text: b"b === ".to_vec(),
};
let inverse_edit1 = invert_edit(&source_code, &edit1);
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, edit1);
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, &edit1);
assert_eq!(ranges, vec![range_of(&source_code, "b === null")]);
// Undo
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, inverse_edit1);
let ranges = get_changed_ranges(&mut parser, &mut tree, &mut source_code, &inverse_edit1);
assert_eq!(ranges, vec![range_of(&source_code, "null")]);
}
}
@ -700,9 +700,9 @@ fn get_changed_ranges(
parser: &mut Parser,
tree: &mut Tree,
source_code: &mut Vec<u8>,
edit: Edit,
edit: &Edit,
) -> Vec<Range> {
perform_edit(tree, source_code, &edit).unwrap();
perform_edit(tree, source_code, edit).unwrap();
let new_tree = parser.parse(&source_code, Some(tree)).unwrap();
let result = tree.changed_ranges(&new_tree).collect();
*tree = new_tree;

View file

@ -16,7 +16,7 @@ fn test_wasm_stdlib_symbols() {
symbols,
{
let mut symbols = symbols.clone();
symbols.sort();
symbols.sort_unstable();
symbols
},
"symbols aren't sorted"
@ -34,11 +34,10 @@ fn test_load_wasm_language() {
let mut store = WasmStore::new(ENGINE.clone()).unwrap();
let mut parser = Parser::new();
let wasm_cpp = fs::read(&WASM_DIR.join(format!("tree-sitter-cpp.wasm"))).unwrap();
let wasm_rs = fs::read(&WASM_DIR.join(format!("tree-sitter-rust.wasm"))).unwrap();
let wasm_rb = fs::read(&WASM_DIR.join(format!("tree-sitter-ruby.wasm"))).unwrap();
let wasm_typescript =
fs::read(&WASM_DIR.join(format!("tree-sitter-typescript.wasm"))).unwrap();
let wasm_cpp = fs::read(WASM_DIR.join("tree-sitter-cpp.wasm")).unwrap();
let wasm_rs = fs::read(WASM_DIR.join("tree-sitter-rust.wasm")).unwrap();
let wasm_rb = fs::read(WASM_DIR.join("tree-sitter-ruby.wasm")).unwrap();
let wasm_typescript = fs::read(WASM_DIR.join("tree-sitter-typescript.wasm")).unwrap();
let language_rust = store.load_language("rust", &wasm_rs).unwrap();
let language_cpp = store.load_language("cpp", &wasm_cpp).unwrap();
@ -108,9 +107,8 @@ fn test_load_and_reload_wasm_language() {
allocations::record(|| {
let mut store = WasmStore::new(ENGINE.clone()).unwrap();
let wasm_rust = fs::read(&WASM_DIR.join(format!("tree-sitter-rust.wasm"))).unwrap();
let wasm_typescript =
fs::read(&WASM_DIR.join(format!("tree-sitter-typescript.wasm"))).unwrap();
let wasm_rust = fs::read(WASM_DIR.join("tree-sitter-rust.wasm")).unwrap();
let wasm_typescript = fs::read(WASM_DIR.join("tree-sitter-typescript.wasm")).unwrap();
let language_rust = store.load_language("rust", &wasm_rust).unwrap();
let language_typescript = store.load_language("typescript", &wasm_typescript).unwrap();
@ -133,11 +131,11 @@ fn test_load_and_reload_wasm_language() {
fn test_load_wasm_errors() {
allocations::record(|| {
let mut store = WasmStore::new(ENGINE.clone()).unwrap();
let wasm = fs::read(&WASM_DIR.join(format!("tree-sitter-rust.wasm"))).unwrap();
let wasm = fs::read(WASM_DIR.join("tree-sitter-rust.wasm")).unwrap();
let bad_wasm = &wasm[1..];
assert_eq!(
store.load_language("rust", &bad_wasm).unwrap_err(),
store.load_language("rust", bad_wasm).unwrap_err(),
WasmError {
kind: WasmErrorKind::Parse,
message: "failed to parse dylink section of wasm module".into(),

View file

@ -57,10 +57,10 @@ fn main() {
}
#[cfg(feature = "bindgen")]
fn generate_bindings(out_dir: &PathBuf) {
fn generate_bindings(out_dir: &Path) {
const HEADER_PATH: &str = "include/tree_sitter/api.h";
println!("cargo:rerun-if-changed={}", HEADER_PATH);
println!("cargo:rerun-if-changed={HEADER_PATH}");
let no_copy = [
"TSInput",

View file

@ -44,13 +44,13 @@ impl WasmStore {
let mut error = MaybeUninit::<ffi::TSWasmError>::uninit();
let engine = Box::new(wasm_engine_t { engine });
let store = ffi::ts_wasm_store_new(
Box::leak(engine) as *mut wasm_engine_t as *mut _,
(Box::leak(engine) as *mut wasm_engine_t).cast(),
error.as_mut_ptr(),
);
if store.is_null() {
Err(WasmError::new(error.assume_init()))
} else {
Ok(WasmStore(store))
Ok(Self(store))
}
}
}
@ -62,7 +62,7 @@ impl WasmStore {
let language = ffi::ts_wasm_store_load_language(
self.0,
name.as_ptr(),
bytes.as_ptr() as *const c_char,
bytes.as_ptr().cast::<c_char>(),
bytes.len() as u32,
error.as_mut_ptr(),
);
@ -74,15 +74,16 @@ impl WasmStore {
}
}
#[must_use]
pub fn language_count(&self) -> usize {
unsafe { ffi::ts_wasm_store_language_count(self.0) as usize }
unsafe { ffi::ts_wasm_store_language_count(self.0) }
}
}
impl WasmError {
unsafe fn new(error: ffi::TSWasmError) -> Self {
let message = CStr::from_ptr(error.message).to_str().unwrap().to_string();
(FREE_FN)(error.message as *mut _);
(FREE_FN)(error.message.cast());
Self {
kind: match error.kind {
ffi::TSWasmErrorKindParse => WasmErrorKind::Parse,
@ -96,6 +97,7 @@ impl WasmError {
}
impl Language {
#[must_use]
pub fn is_wasm(&self) -> bool {
unsafe { ffi::ts_language_is_wasm(self.0) }
}