Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
513 changes: 372 additions & 141 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ test = true
default = []

[dependencies]
deno_ast = { version = "0.45.0", features = ["scopes", "transforms", "utils", "visit", "view", "react"] }
deno_ast = { version = "0.46.0", features = ["scopes", "transforms", "utils", "visit", "view", "react"] }
log = "0.4.20"
serde = { version = "1.0.195", features = ["derive"] }
serde_json = "1.0.111"
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[toolchain]
channel = "1.80.0"
channel = "1.85.0"
components = ["clippy", "rustfmt"]
30 changes: 16 additions & 14 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use deno_ast::{MediaType, ModuleSpecifier};
use deno_ast::{MultiThreadedComments, Scope};
use std::borrow::Cow;
use std::collections::{HashMap, HashSet};
use std::sync::Arc;
use std::rc::Rc;

/// `Context` stores all data needed to perform linting of a particular file.
pub struct Context<'a> {
Expand All @@ -37,9 +37,9 @@ pub struct Context<'a> {
traverse_flow: TraverseFlow,
check_unknown_rules: bool,
#[allow(clippy::redundant_allocation)] // This type comes from SWC.
jsx_factory: Option<Arc<Box<Expr>>>,
jsx_factory: Option<Rc<Box<Expr>>>,
#[allow(clippy::redundant_allocation)] // This type comes from SWC.
jsx_fragment_factory: Option<Arc<Box<Expr>>>,
jsx_fragment_factory: Option<Rc<Box<Expr>>>,
}

impl<'a> Context<'a> {
Expand Down Expand Up @@ -81,24 +81,26 @@ impl<'a> Context<'a> {

if jsx_factory.is_none() {
if let Some(factory) = default_jsx_factory {
jsx_factory =
Some(deno_ast::swc::transforms::react::parse_expr_for_jsx(
jsx_factory = Some(Rc::new(
deno_ast::swc::transforms::react::parse_expr_for_jsx(
&SourceMap::default(),
"jsx",
factory,
Rc::new(factory),
top_level_mark,
));
),
));
}
}
if jsx_fragment_factory.is_none() {
if let Some(factory) = default_jsx_fragment_factory {
jsx_fragment_factory =
Some(deno_ast::swc::transforms::react::parse_expr_for_jsx(
jsx_fragment_factory = Some(Rc::new(
deno_ast::swc::transforms::react::parse_expr_for_jsx(
&SourceMap::default(),
"jsxFragment",
factory,
Rc::new(factory),
top_level_mark,
));
),
));
}
}
});
Expand Down Expand Up @@ -180,15 +182,15 @@ impl<'a> Context<'a> {
/// pragma or using a default). If this file is not JSX, uses the automatic
/// transform, or the default factory is not specified, this will return
/// `None`.
pub fn jsx_factory(&self) -> Option<Arc<Box<Expr>>> {
pub fn jsx_factory(&self) -> Option<Rc<Box<Expr>>> {
self.jsx_factory.clone()
}

/// Get the JSX fragment factory expression for this file, if one is specified
/// (via pragma or using a default). If this file is not JSX, uses the
/// automatic transform, or the default factory is not specified, this will
/// return `None`.
pub fn jsx_fragment_factory(&self) -> Option<Arc<Box<Expr>>> {
pub fn jsx_fragment_factory(&self) -> Option<Rc<Box<Expr>>> {
self.jsx_fragment_factory.clone()
}

Expand Down Expand Up @@ -275,7 +277,7 @@ impl<'a> Context<'a> {
if self
.file_ignore_directive
.as_ref()
.map_or(false, |file_ignore| file_ignore.has_code(CODE))
.is_some_and(|file_ignore| file_ignore.has_code(CODE))
{
return vec![];
}
Expand Down
29 changes: 15 additions & 14 deletions src/control_flow/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use deno_ast::swc::ast::*;
use deno_ast::swc::common::SyntaxContext;
use deno_ast::swc::utils::ExprCtx;
use deno_ast::swc::{
ecma_visit::{noop_visit_type, Visit, VisitWith},
utils::{ExprExt, Value},
visit::{noop_visit_type, Visit, VisitWith},
};
use deno_ast::view;
use deno_ast::SourcePos;
Expand All @@ -34,6 +34,8 @@ impl ControlFlow {
expr_ctxt: ExprCtx {
unresolved_ctxt,
is_unresolved_ref_safe: false,
in_strict: true,
remaining_depth: 4, // this is the swc default
},
};
match program {
Expand Down Expand Up @@ -83,12 +85,12 @@ impl Metadata {
pub fn stops_execution(&self) -> bool {
self
.end
.map_or(false, |d| matches!(d, End::Forced { .. } | End::Break))
.is_some_and(|d| matches!(d, End::Forced { .. } | End::Break))
}

/// Returns true if a node doesn't prevent further execution.
pub fn continues_execution(&self) -> bool {
self.end.map_or(true, |d| d == End::Continue)
self.end.is_none_or(|d| d == End::Continue)
}
}

Expand Down Expand Up @@ -241,7 +243,7 @@ impl Analyzer<'_> {
let mut child = Analyzer {
info: take(&mut self.info),
scope: Scope::new(Some(&self.scope), kind.clone()),
expr_ctxt: self.expr_ctxt.clone(),
expr_ctxt: self.expr_ctxt,
};
match kind {
BlockKind::Function => {}
Expand Down Expand Up @@ -567,7 +569,7 @@ impl Visit for Analyzer<'_> {
let scope_end = self
.scope
.end
.map_or(false, |d| matches!(d, End::Forced { .. } | End::Break));
.is_some_and(|d| matches!(d, End::Forced { .. } | End::Break));

let unreachable = if scope_end {
// Although execution is ended, we should handle hoisting.
Expand Down Expand Up @@ -604,7 +606,7 @@ impl Visit for Analyzer<'_> {
n.test.visit_with(self);

let mut forced_end = None;
let expr_ctxt = self.expr_ctxt.clone();
let expr_ctxt = self.expr_ctxt;

self.with_child_scope(BlockKind::Loop, n.body.start(), |a| {
n.body.visit_with(a);
Expand All @@ -622,8 +624,7 @@ impl Visit for Analyzer<'_> {
forced_end = Some(end);
}
Some(test) => {
if matches!(test.cast_to_bool(&expr_ctxt), (_, Value::Known(true)))
{
if matches!(test.cast_to_bool(expr_ctxt), (_, Value::Known(true))) {
a.mark_as_end(n.start(), end);
forced_end = Some(end);
}
Expand Down Expand Up @@ -670,15 +671,15 @@ impl Visit for Analyzer<'_> {

fn visit_while_stmt(&mut self, n: &WhileStmt) {
let body_lo = n.body.start();
let expr_ctxt = self.expr_ctxt.clone();
let expr_ctxt = self.expr_ctxt;

self.with_child_scope(BlockKind::Loop, body_lo, |a| {
n.body.visit_with(a);

let unconditionally_enter =
matches!(n.test.cast_to_bool(&expr_ctxt), (_, Value::Known(true)));
matches!(n.test.cast_to_bool(expr_ctxt), (_, Value::Known(true)));
let end_reason = a.get_end_reason(body_lo);
let return_or_throw = end_reason.map_or(false, |e| e.is_forced());
let return_or_throw = end_reason.is_some_and(|e| e.is_forced());
let has_break = matches!(a.scope.found_break, Some(None));

if unconditionally_enter && return_or_throw && !has_break {
Expand All @@ -701,15 +702,15 @@ impl Visit for Analyzer<'_> {

fn visit_do_while_stmt(&mut self, n: &DoWhileStmt) {
let body_lo = n.body.start();
let expr_ctxt = self.expr_ctxt.clone();
let expr_ctxt = self.expr_ctxt;

self.with_child_scope(BlockKind::Loop, body_lo, |a| {
n.body.visit_with(a);

let end_reason = a.get_end_reason(body_lo);
let return_or_throw = end_reason.map_or(false, |e| e.is_forced());
let return_or_throw = end_reason.is_some_and(|e| e.is_forced());
let infinite_loop =
matches!(n.test.cast_to_bool(&expr_ctxt), (_, Value::Known(true)))
matches!(n.test.cast_to_bool(expr_ctxt), (_, Value::Known(true)))
&& a.scope.found_break.is_none();
let has_break = matches!(a.scope.found_break, Some(None));

Expand Down
7 changes: 7 additions & 0 deletions src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,12 @@ pub trait Handler {
_ctx: &mut Context,
) {
}
fn ts_import_call_options(
&mut self,
_n: &ast_view::TsImportCallOptions,
_ctx: &mut Context,
) {
}
fn ts_import_equal_decl(
&mut self,
_n: &ast_view::TsImportEqualsDecl,
Expand Down Expand Up @@ -663,6 +669,7 @@ pub trait Traverse: Handler {
TsExternalModuleRef(n) => self.ts_external_module_ref(n, ctx),
TsFnType(n) => self.ts_fn_type(n, ctx),
TsGetterSignature(n) => self.ts_getter_signature(n, ctx),
TsImportCallOptions(n) => self.ts_import_call_options(n, ctx),
TsImportEqualsDecl(n) => self.ts_import_equal_decl(n, ctx),
TsImportType(n) => self.ts_import_type(n, ctx),
TsIndexSignature(n) => self.ts_index_signature(n, ctx),
Expand Down
10 changes: 5 additions & 5 deletions src/rules/adjacent_overload_signatures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,14 @@ trait ExtractMethod {
fn get_method(&self) -> Option<Method>;
}

impl<'a> ExtractMethod for ast_view::ExportDecl<'a> {
impl ExtractMethod for ast_view::ExportDecl<'_> {
fn get_method(&self) -> Option<Method> {
let method_name = extract_ident_from_decl(&self.decl);
method_name.map(Method::Method)
}
}

impl<'a> ExtractMethod for ast_view::Stmt<'a> {
impl ExtractMethod for ast_view::Stmt<'_> {
fn get_method(&self) -> Option<Method> {
let method_name = match self {
ast_view::Stmt::Decl(ref decl) => extract_ident_from_decl(decl),
Expand All @@ -143,7 +143,7 @@ impl<'a> ExtractMethod for ast_view::Stmt<'a> {
}
}

impl<'a> ExtractMethod for ast_view::ModuleItem<'a> {
impl ExtractMethod for ast_view::ModuleItem<'_> {
fn get_method(&self) -> Option<Method> {
use deno_ast::view::{ModuleDecl, ModuleItem};
match self {
Expand All @@ -156,7 +156,7 @@ impl<'a> ExtractMethod for ast_view::ModuleItem<'a> {
}
}

impl<'a> ExtractMethod for ast_view::ClassMember<'a> {
impl ExtractMethod for ast_view::ClassMember<'_> {
fn get_method(&self) -> Option<Method> {
use deno_ast::view::{ClassMember, ClassMethod};
match self {
Expand All @@ -177,7 +177,7 @@ impl<'a> ExtractMethod for ast_view::ClassMember<'a> {
}
}

impl<'a> ExtractMethod for ast_view::TsTypeElement<'a> {
impl ExtractMethod for ast_view::TsTypeElement<'_> {
fn get_method(&self) -> Option<Method> {
use deno_ast::view::{Expr, Lit, TsMethodSignature, TsTypeElement};
match self {
Expand Down
8 changes: 4 additions & 4 deletions src/rules/getter_return.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ use deno_ast::swc::ast::{
MethodProp, ObjectLit, OptCall, OptChainBase, PrivateMethod, Prop, PropName,
PropOrSpread, ReturnStmt,
};
use deno_ast::swc::visit::noop_visit_type;
use deno_ast::swc::visit::Visit;
use deno_ast::swc::visit::VisitWith;
use deno_ast::swc::ecma_visit::noop_visit_type;
use deno_ast::swc::ecma_visit::Visit;
use deno_ast::swc::ecma_visit::VisitWith;
use deno_ast::SourceRange;
use deno_ast::SourceRangedForSpanned;
use derive_more::Display;
Expand Down Expand Up @@ -269,7 +269,7 @@ impl<'c, 'view> GetterReturnVisitor<'c, 'view> {
}
}

impl<'c, 'view> Visit for GetterReturnVisitor<'c, 'view> {
impl Visit for GetterReturnVisitor<'_, '_> {
noop_visit_type!();

fn visit_fn_decl(&mut self, fn_decl: &FnDecl) {
Expand Down
2 changes: 1 addition & 1 deletion src/rules/no_await_in_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ impl Handler for NoAwaitInLoopHandler {
stmt
.init
.as_ref()
.map_or(true, |init| !init.range().contains(&await_expr.range()))
.is_none_or(|init| !init.range().contains(&await_expr.range()))
}
WhileStmt(_) | DoWhileStmt(_) => true,
_ => {
Expand Down
4 changes: 2 additions & 2 deletions src/rules/no_constant_condition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::tags::{self, Tags};
use crate::Program;
use crate::ProgramRef;
use deno_ast::swc::ast::{BinaryOp, CondExpr, Expr, IfStmt, Lit, UnaryOp};
use deno_ast::swc::visit::{noop_visit_type, Visit, VisitWith};
use deno_ast::swc::ecma_visit::{noop_visit_type, Visit, VisitWith};
use deno_ast::SourceRange;
use deno_ast::SourceRangedForSpanned;
use derive_more::Display;
Expand Down Expand Up @@ -205,7 +205,7 @@ fn check_short_circuit(expr: &Expr, operator: BinaryOp) -> bool {
}
}

impl<'c, 'view> Visit for NoConstantConditionVisitor<'c, 'view> {
impl Visit for NoConstantConditionVisitor<'_, '_> {
noop_visit_type!();

fn visit_cond_expr(&mut self, cond_expr: &CondExpr) {
Expand Down
6 changes: 3 additions & 3 deletions src/rules/no_dupe_class_members.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use deno_ast::swc::ast::{
BigInt, Bool, Class, ClassMethod, ComputedPropName, Expr, IdentName, Lit,
MethodKind, Null, Number, PropName, Str, Tpl,
};
use deno_ast::swc::visit::{noop_visit_type, Visit, VisitWith};
use deno_ast::swc::ecma_visit::{noop_visit_type, Visit, VisitWith};
use deno_ast::SourceRange;
use deno_ast::SourceRangedForSpanned;
use derive_more::Display;
Expand Down Expand Up @@ -75,7 +75,7 @@ impl<'c, 'view> NoDupeClassMembersVisitor<'c, 'view> {
}
}

impl<'c, 'view> Visit for NoDupeClassMembersVisitor<'c, 'view> {
impl Visit for NoDupeClassMembersVisitor<'_, '_> {
noop_visit_type!();

fn visit_class(&mut self, class: &Class) {
Expand Down Expand Up @@ -112,7 +112,7 @@ impl<'a, 'b, 'view> ClassVisitor<'a, 'b, 'view> {
}
}

impl<'a, 'b, 'view> Visit for ClassVisitor<'a, 'b, 'view> {
impl Visit for ClassVisitor<'_, '_, '_> {
noop_visit_type!();

fn visit_class(&mut self, class: &Class) {
Expand Down
4 changes: 2 additions & 2 deletions src/rules/no_dupe_else_if.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::tags::{self, Tags};
use crate::Program;
use crate::ProgramRef;
use deno_ast::swc::ast::{BinExpr, BinaryOp, Expr, IfStmt, ParenExpr, Stmt};
use deno_ast::swc::visit::{noop_visit_type, Visit, VisitWith};
use deno_ast::swc::ecma_visit::{noop_visit_type, Visit, VisitWith};
use deno_ast::{SourceRange, SourceRangedForSpanned};
use derive_more::Display;
use std::collections::HashSet;
Expand Down Expand Up @@ -73,7 +73,7 @@ impl<'c, 'view> NoDupeElseIfVisitor<'c, 'view> {
}
}

impl<'c, 'view> Visit for NoDupeElseIfVisitor<'c, 'view> {
impl Visit for NoDupeElseIfVisitor<'_, '_> {
noop_visit_type!();

fn visit_if_stmt(&mut self, if_stmt: &IfStmt) {
Expand Down
6 changes: 3 additions & 3 deletions src/rules/no_duplicate_case.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use crate::tags::{self, Tags};
use crate::Program;
use crate::ProgramRef;
use deno_ast::swc::ast::{Expr, SwitchStmt};
use deno_ast::swc::visit::noop_visit_type;
use deno_ast::swc::visit::{Visit, VisitWith};
use deno_ast::swc::ecma_visit::noop_visit_type;
use deno_ast::swc::ecma_visit::{Visit, VisitWith};
use deno_ast::SourceRangedForSpanned;
use derive_more::Display;
use std::collections::HashSet;
Expand Down Expand Up @@ -63,7 +63,7 @@ impl<'c, 'view> NoDuplicateCaseVisitor<'c, 'view> {
}
}

impl<'c, 'view> Visit for NoDuplicateCaseVisitor<'c, 'view> {
impl Visit for NoDuplicateCaseVisitor<'_, '_> {
noop_visit_type!();

fn visit_switch_stmt(&mut self, switch_stmt: &SwitchStmt) {
Expand Down
Loading
Loading