Skip to content

Commit

Permalink
Merge branch 'main' into fixer-no-length-as-slice-end
Browse files Browse the repository at this point in the history
  • Loading branch information
rzvxa authored Aug 9, 2024
2 parents 60d6478 + 92777d0 commit f529737
Show file tree
Hide file tree
Showing 23 changed files with 832 additions and 174 deletions.
9 changes: 9 additions & 0 deletions crates/oxc_ast/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,12 @@ mod ts;
use macros::inherit_variants;

pub use self::{js::*, jsx::*, literal::*, ts::*};

// Re-export AST types from other crates
pub use oxc_span::{Atom, Language, LanguageVariant, ModuleKind, SourceType, Span};
pub use oxc_syntax::{
number::{BigintBase, NumberBase},
operator::{
AssignmentOperator, BinaryOperator, LogicalOperator, UnaryOperator, UpdateOperator,
},
};
520 changes: 517 additions & 3 deletions crates/oxc_ast/src/generated/assert_layouts.rs

Large diffs are not rendered by default.

7 changes: 0 additions & 7 deletions crates/oxc_ast/src/generated/ast_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@
)]

use oxc_allocator::{Allocator, Box, IntoIn, Vec};
use oxc_span::{Atom, SourceType, Span};
use oxc_syntax::{
number::{BigintBase, NumberBase},
operator::{
AssignmentOperator, BinaryOperator, LogicalOperator, UnaryOperator, UpdateOperator,
},
};

#[allow(clippy::wildcard_imports)]
use crate::ast::*;
Expand Down
1 change: 1 addition & 0 deletions crates/oxc_ast/src/generated/ast_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use oxc_span::{GetSpan, Span};

#[allow(clippy::wildcard_imports)]
use crate::ast::*;

#[derive(Debug, Clone, Copy)]
Expand Down
1 change: 1 addition & 0 deletions crates/oxc_ast/src/generated/derive_clone_in.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use oxc_allocator::{Allocator, CloneIn};

#[allow(clippy::wildcard_imports)]
use crate::ast::*;

impl<'alloc> CloneIn<'alloc> for BooleanLiteral {
Expand Down
3 changes: 2 additions & 1 deletion crates/oxc_ast/src/generated/derive_get_span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@

#![allow(clippy::match_same_arms)]

use oxc_span::{GetSpan, Span};
use oxc_span::GetSpan;

#[allow(clippy::wildcard_imports)]
use crate::ast::*;

impl GetSpan for BooleanLiteral {
Expand Down
3 changes: 2 additions & 1 deletion crates/oxc_ast/src/generated/derive_get_span_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@

#![allow(clippy::match_same_arms)]

use oxc_span::{GetSpanMut, Span};
use oxc_span::GetSpanMut;

#[allow(clippy::wildcard_imports)]
use crate::ast::*;

impl GetSpanMut for BooleanLiteral {
Expand Down
4 changes: 3 additions & 1 deletion crates/oxc_ast/src/generated/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ use std::cell::Cell;
use oxc_allocator::Vec;
use oxc_syntax::scope::{ScopeFlags, ScopeId};

use crate::{ast::*, ast_kind::AstKind};
#[allow(clippy::wildcard_imports)]
use crate::ast::*;
use crate::ast_kind::AstKind;

use walk::*;

Expand Down
4 changes: 3 additions & 1 deletion crates/oxc_ast/src/generated/visit_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ use std::cell::Cell;
use oxc_allocator::Vec;
use oxc_syntax::scope::{ScopeFlags, ScopeId};

use crate::{ast::*, ast_kind::AstType};
#[allow(clippy::wildcard_imports)]
use crate::ast::*;
use crate::ast_kind::AstType;

use walk_mut::*;

Expand Down
66 changes: 48 additions & 18 deletions crates/oxc_linter/src/rules/typescript/prefer_namespace_keyword.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use oxc_ast::{
ast::{TSModuleDeclarationKind, TSModuleDeclarationName},
ast::{TSModuleDeclaration, TSModuleDeclarationKind, TSModuleDeclarationName},
AstKind,
};
use oxc_diagnostics::OxcDiagnostic;
Expand Down Expand Up @@ -34,13 +34,27 @@ declare_oxc_lint!(
fix
);

fn is_nest_module(node: &AstNode, ctx: &LintContext<'_>) -> bool {
ctx.nodes()
.parent_node(node.id())
.map_or(false, |parent_node| is_valid_module_node(parent_node))
}

fn is_valid_module_node(node: &AstNode) -> bool {
matches!(node.kind(), AstKind::TSModuleDeclaration(module) if is_valid_module(module))
}

fn is_valid_module(module: &TSModuleDeclaration) -> bool {
!module.id.is_string_literal()
&& matches!(module.id, TSModuleDeclarationName::Identifier(_))
&& module.kind == TSModuleDeclarationKind::Module
}

impl Rule for PreferNamespaceKeyword {
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
let AstKind::TSModuleDeclaration(module) = node.kind() else { return };
if module.id.is_string_literal()
|| !matches!(module.id, TSModuleDeclarationName::Identifier(_))
|| module.kind != TSModuleDeclarationKind::Module
{

if !is_valid_module(module) || is_nest_module(node, ctx) {
return;
}

Expand Down Expand Up @@ -74,32 +88,48 @@ fn test() {

let fail = vec![
"module foo {}",
"module A.B {}",
"declare module foo {}",
"
declare module foo {
declare module bar {}
}
",
"declare global {
declare module foo {
declare module bar {}
}
",
"
declare global {
module foo {}
}
",
];

let fix = vec![
("module foo {}", "namespace foo {}", None),
("module A.B {}", "namespace A.B {}", None),
(
"
module A {
module B {}
}
",
"
namespace A {
namespace B {}
}
",
None,
),
("declare module foo {}", "declare namespace foo {}", None),
(
"
declare module foo {
declare module bar {}
}
",
declare module foo {
declare module bar {}
}
",
"
declare namespace foo {
declare namespace bar {}
}
",
declare namespace foo {
declare namespace bar {}
}
",
None,
),
];
Expand Down
35 changes: 21 additions & 14 deletions crates/oxc_linter/src/snapshots/prefer_namespace_keyword.snap
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ source: crates/oxc_linter/src/tester.rs
╰────
help: Replace `module` with `namespace`.

typescript-eslint(prefer-namespace-keyword): Use 'namespace' instead of 'module' to declare custom TypeScript modules.
╭─[prefer_namespace_keyword.tsx:1:1]
1module A.B {}
· ─────────────
╰────
help: Replace `module` with `namespace`.

typescript-eslint(prefer-namespace-keyword): Use 'namespace' instead of 'module' to declare custom TypeScript modules.
╭─[prefer_namespace_keyword.tsx:1:1]
1declare module foo {}
Expand All @@ -16,29 +23,29 @@ source: crates/oxc_linter/src/tester.rs
help: Replace `module` with `namespace`.

typescript-eslint(prefer-namespace-keyword): Use 'namespace' instead of 'module' to declare custom TypeScript modules.
╭─[prefer_namespace_keyword.tsx:2:4]
╭─[prefer_namespace_keyword.tsx:2:9]
1
2 │ ╭─▶ declare module foo {
3 │ │ declare module bar {}
4 │ ╰─▶ }
5
2 │ ╭─▶ declare module foo {
3 │ │ declare module bar {}
4 │ ╰─▶ }
5
╰────
help: Replace `module` with `namespace`.

typescript-eslint(prefer-namespace-keyword): Use 'namespace' instead of 'module' to declare custom TypeScript modules.
╭─[prefer_namespace_keyword.tsx:3:6]
2 declare module foo {
3 declare module bar {}
· ─────────────────────
4 }
╭─[prefer_namespace_keyword.tsx:3:11]
2declare module foo {
3declare module bar {}
· ─────────────────────
4 │ }
╰────
help: Replace `module` with `namespace`.

typescript-eslint(prefer-namespace-keyword): Use 'namespace' instead of 'module' to declare custom TypeScript modules.
╭─[prefer_namespace_keyword.tsx:2:13]
1 declare global {
2module foo {}
╭─[prefer_namespace_keyword.tsx:3:13]
2 declare global {
3module foo {}
· ─────────────
3 │ }
4 │ }
╰────
help: Replace `module` with `namespace`.
120 changes: 93 additions & 27 deletions tasks/ast_codegen/src/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,69 @@ use syn::parse_file;

static INSERT_MACRO_IDENT: &str = "insert";
static ENDL_MACRO_IDENT: &str = "endl";
static WHITE_SPACES: &str = " ";
static WHITE_SPACES: &str = " \t";

/// Pretty print
pub fn pretty_print(input: &TokenStream) -> String {
let result = prettyplease::unparse(&parse_file(input.to_string().as_str()).unwrap());
// `insert!` and `endl!` macros are not currently used
// let result = ENDL_REGEX.replace_all(&result, EndlReplacer);
// let result = INSERT_REGEX.replace_all(&result, InsertReplacer).to_string();
let result = COMMENT_REGEX.replace_all(&result, CommentReplacer).to_string();
result
}

/// Run `cargo fmt`
pub fn cargo_fmt() {
Command::new("cargo").arg("fmt").status().unwrap();
}

/// Replace doc comments which start with `@` with plain comments or line breaks.
///
/// Original comment can be either `///@` or `//!@`.
///
/// * `///@ foo` becomes `// foo`.
/// * `//!@ foo` becomes `// foo`.
/// * `///@@line_break` is removed - i.e. line break.
/// * `//!@@line_break` is removed - i.e. line break.
///
/// `quote!` macro ignores plain comments, but we can use these to generate plain comments
/// in generated code.
///
/// To dynamically generate a comment:
/// ```
/// let comment = format!("@ NOTE: {} doesn't exist!", name);
/// quote!(#[doc = #comment])
/// // or `quote!(#![doc = #comment])`
/// ```
///
/// `//!@@line_break` can be used to insert a line break in a position where `///@@line_break`
/// is not valid syntax e.g. before an `#![allow(...)]`.
struct CommentReplacer;

impl Replacer for CommentReplacer {
fn replace_append(&mut self, caps: &Captures, dst: &mut String) {
assert_eq!(caps.len(), 2);
let body = caps.get(1).unwrap().as_str();
if body != "@line_break" {
dst.push_str("//");
dst.push_str(body);
}
}
}

lazy_static! {
static ref COMMENT_REGEX: Regex =
Regex::new(format!(r"[{WHITE_SPACES}]*//[/!]@(.*)").as_str()).unwrap();
}

/// Replace `insert!` macro calls with the contents of the `insert!`.
///
/// e.g. `insert!("#![allow(dead_code)]")` is replaced by `#![allow(dead_code)]`.
///
/// We use this when inserting outer attributes (`#![allow(unused)]`) or plain comments (`//` not `///`).
/// `quote!` macro ignores plain comments, so it's not possible to produce them otherwise.
#[allow(dead_code)] // `insert!` macro is not currently used
struct InsertReplacer;

impl Replacer for InsertReplacer {
Expand All @@ -21,36 +82,41 @@ impl Replacer for InsertReplacer {
}
}

lazy_static! {
static ref INSERT_REGEX: Regex = Regex::new(
format!(
r#"(?m)^[{WHITE_SPACES}]*{INSERT_MACRO_IDENT}!\([\n\s\S]*?\"([\n\s\S]*?)\"[\n\s\S]*?\);$"#
)
.as_str()
)
.unwrap();
}

/// Remove `endl!();`, so it produces a line break.
///
/// e.g.:
/// ```
/// use oxc_allocator::Allocator;
/// endl!();
/// use oxc_ast::*;
/// ```
/// becomes:
/// ```
/// use oxc_allocator::Allocator;
///
/// use oxc_ast::*;
/// ```
///
/// We use `endl!();` because `quote!` macro ignores whitespace,
/// so we have to use another means to generate line breaks.
#[allow(dead_code)] // `endl!` macro is not currently used
struct EndlReplacer;

impl Replacer for EndlReplacer {
fn replace_append(&mut self, _: &Captures, _: &mut String) {}
}

/// Pretty Print
pub fn pprint(input: &TokenStream) -> String {
lazy_static! {
static ref INSERT_REGEX: Regex = Regex::new(
format!(
r#"(?m)^[{WHITE_SPACES}]*{INSERT_MACRO_IDENT}!\([\n\s\S]*?\"([\n\s\S]*?)\"[\n\s\S]*?\);$"#
)
.as_str()
)
.unwrap();
};

lazy_static! {
static ref ENDL_REGEX: Regex =
Regex::new(format!(r"[{WHITE_SPACES}]*{ENDL_MACRO_IDENT}!\(\);").as_str()).unwrap();
};

let result = prettyplease::unparse(&parse_file(input.to_string().as_str()).unwrap());
let result = ENDL_REGEX.replace_all(&result, EndlReplacer);
let result = INSERT_REGEX.replace_all(&result, InsertReplacer).to_string();
result
}

/// Runs cargo fmt.
pub fn cargo_fmt() {
Command::new("cargo").arg("fmt").status().unwrap();
lazy_static! {
static ref ENDL_REGEX: Regex =
Regex::new(format!(r"[{WHITE_SPACES}]*{ENDL_MACRO_IDENT}!\(\);").as_str()).unwrap();
}
Loading

0 comments on commit f529737

Please sign in to comment.