Skip to content

Commit

Permalink
refactor(js_syntax): add TsDeclarationModule node
Browse files Browse the repository at this point in the history
  • Loading branch information
Conaclos committed Nov 15, 2024
1 parent e936902 commit 60b3242
Show file tree
Hide file tree
Showing 22 changed files with 419 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use biome_analyze::{context::RuleContext, declare_lint_rule, Ast, Rule, RuleDiagnostic};
use biome_analyze::{RuleSource, RuleSourceKind};
use biome_console::markup;
use biome_js_syntax::{JsLanguage, JsModule};
use biome_js_syntax::{AnyJsRoot, JsLanguage, JsSyntaxNode};
use biome_rowan::{AstNode, Direction, SyntaxTriviaPiece, TextRange};

const IRREGULAR_WHITESPACES: &[char; 22] = &[
Expand Down Expand Up @@ -48,14 +48,13 @@ declare_lint_rule! {
}

impl Rule for NoIrregularWhitespace {
type Query = Ast<JsModule>;
type Query = Ast<AnyJsRoot>;
type State = TextRange;
type Signals = Box<[Self::State]>;
type Options = ();

fn run(ctx: &RuleContext<Self>) -> Self::Signals {
let node = ctx.query();
get_irregular_whitespace(node).into_boxed_slice()
get_irregular_whitespace(ctx.query().syntax()).into_boxed_slice()
}

fn diagnostic(_ctx: &RuleContext<Self>, range: &Self::State) -> Option<RuleDiagnostic> {
Expand All @@ -77,8 +76,7 @@ impl Rule for NoIrregularWhitespace {
}
}

fn get_irregular_whitespace(node: &JsModule) -> Vec<TextRange> {
let syntax = node.syntax();
fn get_irregular_whitespace(syntax: &JsSyntaxNode) -> Vec<TextRange> {
let mut all_whitespaces_trivia: Vec<SyntaxTriviaPiece<JsLanguage>> = vec![];
let is_whitespace = |trivia: &SyntaxTriviaPiece<JsLanguage>| {
trivia.is_whitespace() && !trivia.text().replace(' ', "").is_empty()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use biome_analyze::{
use biome_console::markup;
use biome_js_syntax::{
AnyJsModuleItem, JsClassDeclaration, JsFunctionDeclaration, JsModule, JsModuleItemList,
TsDeclareStatement, TsInterfaceDeclaration, TsTypeAliasDeclaration, TsTypeMemberList,
TsDeclarationModule, TsDeclareStatement, TsInterfaceDeclaration, TsTypeAliasDeclaration,
TsTypeMemberList,
};
use biome_rowan::{declare_node_union, AstNode, TextRange, TokenText};
use rustc_hash::FxHashSet;
Expand Down Expand Up @@ -129,10 +130,8 @@ impl Rule for UseAdjacentOverloadSignatures {
// Handle export function foo() {}
DeclarationOrModuleNode::JsFunctionDeclaration(node) => collect_function(node),
// Handle export function foo() {}
DeclarationOrModuleNode::JsModule(node) => {
let items = node.items();
collect_exports(&items)
}
DeclarationOrModuleNode::JsModule(node) => collect_exports(&node.items()),
DeclarationOrModuleNode::TsDeclarationModule(node) => collect_exports(&node.items()),
};

if !methods.is_empty() {
Expand Down Expand Up @@ -317,5 +316,12 @@ fn check_method<T: Clone + Eq + std::hash::Hash + Into<TokenText>>(
}

declare_node_union! {
pub DeclarationOrModuleNode = TsInterfaceDeclaration | TsTypeAliasDeclaration | TsDeclareStatement | JsClassDeclaration | JsModule | JsFunctionDeclaration
pub DeclarationOrModuleNode =
JsClassDeclaration
| JsFunctionDeclaration
| TsInterfaceDeclaration
| TsDeclareStatement
| TsTypeAliasDeclaration
| JsModule
| TsDeclarationModule
}
12 changes: 1 addition & 11 deletions crates/biome_js_analyze/src/lint/performance/no_barrel_file.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use biome_analyze::{context::RuleContext, declare_lint_rule, Rule, RuleDiagnostic};
use biome_analyze::{Ast, RuleSource, RuleSourceKind};
use biome_console::markup;
use biome_js_syntax::{
JsExport, JsExportFromClause, JsExportNamedFromClause, JsFileSource, JsModule,
};
use biome_js_syntax::{JsExport, JsExportFromClause, JsExportNamedFromClause, JsModule};
use biome_rowan::AstNode;

declare_lint_rule! {
Expand Down Expand Up @@ -58,15 +56,7 @@ impl Rule for NoBarrelFile {
type Options = ();

fn run(ctx: &RuleContext<Self>) -> Self::Signals {
if ctx
.source_type::<JsFileSource>()
.language()
.is_definition_file()
{
return None;
}
let items = ctx.query().items();

for item in items {
if let Some(export) = JsExport::cast(item.into()) {
if let Ok(export_from_clause) = export.export_clause() {
Expand Down
10 changes: 5 additions & 5 deletions crates/biome_js_analyze/src/lint/style/use_naming_convention.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1848,14 +1848,14 @@ impl Scope {
/// Returns the scope of `node` or `None` if the scope cannot be determined or
/// if the scope is an external module.
fn from_declaration(node: &AnyJsBindingDeclaration) -> Option<Scope> {
let control_flow_root = node
.syntax()
.ancestors()
.skip(1)
.find(|x| AnyJsControlFlowRoot::can_cast(x.kind()))?;
let control_flow_root = node.syntax().ancestors().skip(1).find(|x| {
AnyJsControlFlowRoot::can_cast(x.kind())
|| x.kind() == JsSyntaxKind::TS_DECLARATION_MODULE
})?;
match control_flow_root.kind() {
JsSyntaxKind::JS_MODULE
| JsSyntaxKind::JS_SCRIPT
| JsSyntaxKind::TS_DECLARATION_MODULE
| JsSyntaxKind::TS_MODULE_DECLARATION => Some(Scope::Global),
// Ignore declarations in an external module declaration
JsSyntaxKind::TS_EXTERNAL_MODULE_DECLARATION => None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,9 @@ impl Rule for NoEvolvingTypes {

fn run(ctx: &RuleContext<Self>) -> Self::Signals {
let source_type = ctx.source_type::<JsFileSource>().language();
let is_ts_source = source_type.is_typescript();
let node = ctx.query();
let is_declaration = source_type.is_definition_file();

if is_declaration || !is_ts_source {
if !source_type.is_typescript() || source_type.is_definition_file() {
return None;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl Rule for NoImplicitAnyLet {
let source_type = ctx.source_type::<JsFileSource>().language();
let node = ctx.query();

if source_type.is_definition_file() || !source_type.is_typescript() || node.is_const() {
if !source_type.is_typescript() || source_type.is_definition_file() || node.is_const() {
return None;
}

Expand Down
43 changes: 43 additions & 0 deletions crates/biome_js_factory/src/generated/node_factory.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 47 additions & 0 deletions crates/biome_js_factory/src/generated/syntax_factory.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions crates/biome_js_formatter/src/comments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,9 @@ fn handle_root_comments(comment: DecoratedComment<JsLanguage>) -> CommentPlaceme
AnyJsRoot::JsScript(script) => {
script.directives().is_empty() && script.statements().is_empty()
}
AnyJsRoot::TsDeclarationModule(module) => {
module.directives().is_empty() && module.items().is_empty()
}
};

if is_blank {
Expand Down
40 changes: 40 additions & 0 deletions crates/biome_js_formatter/src/generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6957,6 +6957,46 @@ impl IntoFormat<JsFormatContext> for biome_js_syntax::TsConstructorType {
)
}
}
impl FormatRule<biome_js_syntax::TsDeclarationModule>
for crate::ts::auxiliary::declaration_module::FormatTsDeclarationModule
{
type Context = JsFormatContext;
#[inline(always)]
fn fmt(
&self,
node: &biome_js_syntax::TsDeclarationModule,
f: &mut JsFormatter,
) -> FormatResult<()> {
FormatNodeRule::<biome_js_syntax::TsDeclarationModule>::fmt(self, node, f)
}
}
impl AsFormat<JsFormatContext> for biome_js_syntax::TsDeclarationModule {
type Format<'a> = FormatRefWithRule<
'a,
biome_js_syntax::TsDeclarationModule,
crate::ts::auxiliary::declaration_module::FormatTsDeclarationModule,
>;
fn format(&self) -> Self::Format<'_> {
#![allow(clippy::default_constructed_unit_structs)]
FormatRefWithRule::new(
self,
crate::ts::auxiliary::declaration_module::FormatTsDeclarationModule::default(),
)
}
}
impl IntoFormat<JsFormatContext> for biome_js_syntax::TsDeclarationModule {
type Format = FormatOwnedWithRule<
biome_js_syntax::TsDeclarationModule,
crate::ts::auxiliary::declaration_module::FormatTsDeclarationModule,
>;
fn into_format(self) -> Self::Format {
#![allow(clippy::default_constructed_unit_structs)]
FormatOwnedWithRule::new(
self,
crate::ts::auxiliary::declaration_module::FormatTsDeclarationModule::default(),
)
}
}
impl FormatRule<biome_js_syntax::TsDeclareFunctionDeclaration>
for crate::ts::declarations::declare_function_declaration::FormatTsDeclareFunctionDeclaration
{
Expand Down
1 change: 1 addition & 0 deletions crates/biome_js_formatter/src/js/any/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ impl FormatRule<AnyJsRoot> for FormatAnyJsRoot {
AnyJsRoot::JsExpressionSnipped(node) => node.format().fmt(f),
AnyJsRoot::JsModule(node) => node.format().fmt(f),
AnyJsRoot::JsScript(node) => node.format().fmt(f),
AnyJsRoot::TsDeclarationModule(node) => node.format().fmt(f),
}
}
}
71 changes: 71 additions & 0 deletions crates/biome_js_formatter/src/ts/auxiliary/declaration_module.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use crate::prelude::*;
use biome_formatter::write;

use crate::utils::FormatInterpreterToken;

use biome_js_syntax::{TsDeclarationModule, TsDeclarationModuleFields};
use biome_rowan::AstNode;

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatTsDeclarationModule;
impl FormatNodeRule<TsDeclarationModule> for FormatTsDeclarationModule {
fn fmt_fields(&self, node: &TsDeclarationModule, f: &mut JsFormatter) -> FormatResult<()> {
let TsDeclarationModuleFields {
bom_token,
interpreter_token,
directives,
items,
eof_token,
} = node.as_fields();

write![
f,
[
bom_token.format(),
FormatInterpreterToken::new(interpreter_token.as_ref()),
format_leading_comments(node.syntax()),
directives.format()
]
]?;

write!(
f,
[
items.format(),
format_trailing_comments(node.syntax()),
format_removed(&eof_token?),
hard_line_break()
]
)
}

fn fmt_leading_comments(
&self,
_: &TsDeclarationModule,
_: &mut JsFormatter,
) -> FormatResult<()> {
// Formatted as part of `fmt_fields`
Ok(())
}

fn fmt_dangling_comments(
&self,
module: &TsDeclarationModule,
f: &mut JsFormatter,
) -> FormatResult<()> {
debug_assert!(
!f.comments().has_dangling_comments(module.syntax()),
"Module should never have dangling comments."
);
Ok(())
}

fn fmt_trailing_comments(
&self,
_: &TsDeclarationModule,
_: &mut JsFormatter,
) -> FormatResult<()> {
// Formatted as part of `fmt_fields`
Ok(())
}
}
1 change: 1 addition & 0 deletions crates/biome_js_formatter/src/ts/auxiliary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub(crate) mod asserts_condition;
pub(crate) mod call_signature_type_member;
pub(crate) mod const_modifier;
pub(crate) mod construct_signature_type_member;
pub(crate) mod declaration_module;
pub(crate) mod declare_modifier;
pub(crate) mod default_type_clause;
pub(crate) mod definite_property_annotation;
Expand Down
Loading

0 comments on commit 60b3242

Please sign in to comment.