use tree_sitter::Node;
use super::DartFile;
use crate::scope_model;
const VETO_KINDS: &[&str] = &[
"if_statement",
"for_statement",
"while_statement",
"do_statement",
"switch_statement",
"switch_expression",
"try_statement",
"catch_clause",
];
const OWNER_KINDS: &[&str] = &[
"function_declaration",
"method_declaration",
"getter_declaration",
"setter_declaration",
"local_function_declaration",
"function_expression",
];
static DART_SEMANTICS: scope_model::Semantics = scope_model::Semantics {
pure,
veto: VETO_KINDS,
owners: OWNER_KINDS,
include_root_scope: false,
};
pub fn used_once_offenses(fm: &DartFile) -> Vec<crate::used_once::UsedOnceOffense> {
scope_model::used_once_offenses(
fm.tree.root_node(),
&|byte| fm.line_col(byte),
&fm.scopes,
&DART_SEMANTICS,
)
}
pub fn never_used_offenses(fm: &DartFile) -> Vec<crate::never_used::NeverUsedOffense> {
scope_model::never_used_offenses(&|byte| fm.line_col(byte), &fm.scopes, &DART_SEMANTICS)
}
fn pure(n: Node) -> bool {
match n.kind() {
"decimal_integer_literal"
| "decimal_floating_point_literal"
| "hex_integer_literal"
| "true"
| "false"
| "null_literal" => true,
"string_literal" => children_pure(n),
"raw_string_literal_double_quotes"
| "raw_string_literal_single_quotes"
| "raw_string_literal_double_quotes_multiple"
| "raw_string_literal_single_quotes_multiple" => true,
"template_chars_single"
| "template_chars_single_single"
| "template_chars_double"
| "template_chars_double_single"
| "template_chars_raw_slash"
| "escape_sequence" => true,
"template_substitution" => false,
"list_literal" | "set_or_map_literal" | "record_literal" => children_pure(n),
"parenthesized_expression"
| "additive_expression"
| "multiplicative_expression"
| "bitwise_and_expression"
| "bitwise_or_expression"
| "bitwise_xor_expression"
| "shift_expression"
| "if_null_expression"
| "unary_expression" => children_pure(n),
_ => false,
}
}
fn children_pure(n: Node) -> bool {
let mut c = n.walk();
n.children(&mut c)
.filter(|ch| ch.is_named())
.all(|ch| pure(ch))
}