mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
refactor(ast)!: replace Modifiers with declare on VariableDeclaration (#3839)
part of #2958
This commit is contained in:
parent
f029273b04
commit
9b38119ec9
25 changed files with 224 additions and 200 deletions
|
|
@ -1,7 +1,6 @@
|
|||
// Silence erroneous warnings from Rust Analyser for `#[derive(Tsify)]`
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use crate::ast::*;
|
||||
use std::cell::Cell;
|
||||
|
||||
use oxc_allocator::{Box, Vec};
|
||||
|
|
@ -17,6 +16,7 @@ use oxc_syntax::{
|
|||
};
|
||||
|
||||
use super::macros::inherit_variants;
|
||||
use super::*;
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
use serde::Serialize;
|
||||
|
|
@ -1000,8 +1000,7 @@ pub struct VariableDeclaration<'a> {
|
|||
pub span: Span,
|
||||
pub kind: VariableDeclarationKind,
|
||||
pub declarations: Vec<'a, VariableDeclarator<'a>>,
|
||||
/// Valid Modifiers: `export`, `declare`
|
||||
pub modifiers: Modifiers<'a>,
|
||||
pub declare: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
// Silence erroneous warnings from Rust Analyser for `#[derive(Tsify)]`
|
||||
#![allow(non_snake_case)]
|
||||
//! AST Definitions
|
||||
//!
|
||||
//! # Enum inheritance
|
||||
|
|
@ -181,3 +183,128 @@ mod ts;
|
|||
use macros::inherit_variants;
|
||||
|
||||
pub use self::{js::*, jsx::*, literal::*, ts::*};
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
use serde::Serialize;
|
||||
#[cfg(feature = "serialize")]
|
||||
use tsify::Tsify;
|
||||
|
||||
use oxc_allocator::Vec;
|
||||
use oxc_span::Span;
|
||||
|
||||
#[derive(Debug, Hash)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
|
||||
#[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))]
|
||||
pub struct Modifier {
|
||||
#[cfg_attr(feature = "serialize", serde(flatten))]
|
||||
pub span: Span,
|
||||
pub kind: ModifierKind,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Hash)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
|
||||
#[cfg_attr(feature = "serialize", serde(transparent))]
|
||||
pub struct Modifiers<'a>(Option<Vec<'a, Modifier>>);
|
||||
|
||||
impl<'a> Modifiers<'a> {
|
||||
pub fn new(modifiers: Vec<'a, Modifier>) -> Self {
|
||||
Self(Some(modifiers))
|
||||
}
|
||||
|
||||
pub fn empty() -> Self {
|
||||
Self(None)
|
||||
}
|
||||
|
||||
pub fn is_none(&self) -> bool {
|
||||
self.0.is_none()
|
||||
}
|
||||
|
||||
pub fn contains(&self, target: ModifierKind) -> bool {
|
||||
self.0
|
||||
.as_ref()
|
||||
.map_or(false, |modifiers| modifiers.iter().any(|modifier| modifier.kind == target))
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = &Modifier> + '_ {
|
||||
self.0.as_ref().into_iter().flat_map(|modifiers| modifiers.iter())
|
||||
}
|
||||
|
||||
/// Find a modifier by kind
|
||||
pub fn find(&self, kind: ModifierKind) -> Option<&Modifier> {
|
||||
self.find_where(|modifier| modifier.kind == kind)
|
||||
}
|
||||
|
||||
pub fn find_where<F>(&self, f: F) -> Option<&Modifier>
|
||||
where
|
||||
F: Fn(&Modifier) -> bool,
|
||||
{
|
||||
self.0.as_ref().and_then(|modifiers| modifiers.iter().find(|modifier| f(modifier)))
|
||||
}
|
||||
|
||||
pub fn is_contains_declare(&self) -> bool {
|
||||
self.contains(ModifierKind::Declare)
|
||||
}
|
||||
|
||||
pub fn is_contains_abstract(&self) -> bool {
|
||||
self.contains(ModifierKind::Abstract)
|
||||
}
|
||||
|
||||
pub fn remove_type_modifiers(&mut self) {
|
||||
if let Some(list) = &mut self.0 {
|
||||
list.retain(|m| !m.kind.is_typescript_syntax());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_modifier(&mut self, modifier: Modifier) {
|
||||
if let Some(list) = self.0.as_mut() {
|
||||
list.push(modifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
|
||||
#[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))]
|
||||
pub enum ModifierKind {
|
||||
Abstract,
|
||||
Accessor,
|
||||
Async,
|
||||
Const,
|
||||
Declare,
|
||||
Default,
|
||||
Export,
|
||||
In,
|
||||
Public,
|
||||
Private,
|
||||
Protected,
|
||||
Readonly,
|
||||
Static,
|
||||
Out,
|
||||
Override,
|
||||
}
|
||||
|
||||
impl ModifierKind {
|
||||
pub fn is_typescript_syntax(&self) -> bool {
|
||||
!matches!(self, Self::Async | Self::Default | Self::Export | Self::Static)
|
||||
}
|
||||
|
||||
pub fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
Self::Abstract => "abstract",
|
||||
Self::Accessor => "accessor",
|
||||
Self::Async => "async",
|
||||
Self::Const => "const",
|
||||
Self::Declare => "declare",
|
||||
Self::Default => "default",
|
||||
Self::Export => "export",
|
||||
Self::In => "in",
|
||||
Self::Public => "public",
|
||||
Self::Private => "private",
|
||||
Self::Protected => "protected",
|
||||
Self::Readonly => "readonly",
|
||||
Self::Static => "static",
|
||||
Self::Out => "out",
|
||||
Self::Override => "override",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ use serde::Serialize;
|
|||
#[cfg(feature = "serialize")]
|
||||
use tsify::Tsify;
|
||||
|
||||
use super::{inherit_variants, js::*, jsx::*, literal::*};
|
||||
use super::{inherit_variants, js::*, jsx::*, literal::*, Modifiers};
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)]
|
||||
|
|
@ -1094,41 +1094,6 @@ pub struct Decorator<'a> {
|
|||
pub expression: Expression<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
|
||||
#[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))]
|
||||
pub enum ModifierKind {
|
||||
Abstract,
|
||||
Accessor,
|
||||
Async,
|
||||
Const,
|
||||
Declare,
|
||||
Default,
|
||||
Export,
|
||||
In,
|
||||
Public,
|
||||
Private,
|
||||
Protected,
|
||||
Readonly,
|
||||
Static,
|
||||
Out,
|
||||
Override,
|
||||
}
|
||||
|
||||
#[derive(Debug, Hash)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
|
||||
#[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))]
|
||||
pub struct Modifier {
|
||||
#[cfg_attr(feature = "serialize", serde(flatten))]
|
||||
pub span: Span,
|
||||
pub kind: ModifierKind,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Hash)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
|
||||
#[cfg_attr(feature = "serialize", serde(transparent))]
|
||||
pub struct Modifiers<'a>(pub(crate) Option<Vec<'a, Modifier>>);
|
||||
|
||||
/// Export Assignment in non-module files
|
||||
///
|
||||
/// `export = foo`
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ impl<'a> AstBuilder<'a> {
|
|||
Span::default(),
|
||||
VariableDeclarationKind::Var,
|
||||
self.new_vec(),
|
||||
Modifiers::empty(),
|
||||
false,
|
||||
);
|
||||
let empty_decl = Declaration::VariableDeclaration(empty_decl);
|
||||
mem::replace(decl, empty_decl)
|
||||
|
|
@ -1167,9 +1167,9 @@ impl<'a> AstBuilder<'a> {
|
|||
span: Span,
|
||||
kind: VariableDeclarationKind,
|
||||
declarations: Vec<'a, VariableDeclarator<'a>>,
|
||||
modifiers: Modifiers<'a>,
|
||||
declare: bool,
|
||||
) -> Box<'a, VariableDeclaration<'a>> {
|
||||
self.alloc(VariableDeclaration { span, kind, declarations, modifiers })
|
||||
self.alloc(VariableDeclaration { span, kind, declarations, declare })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -705,23 +705,23 @@ impl<'a> Declaration<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn modifiers(&self) -> Option<&Modifiers<'a>> {
|
||||
pub fn declare(&self) -> bool {
|
||||
match self {
|
||||
Declaration::VariableDeclaration(decl) => Some(&decl.modifiers),
|
||||
Declaration::FunctionDeclaration(decl) => Some(&decl.modifiers),
|
||||
Declaration::ClassDeclaration(decl) => Some(&decl.modifiers),
|
||||
Declaration::TSEnumDeclaration(decl) => Some(&decl.modifiers),
|
||||
Declaration::TSTypeAliasDeclaration(decl) => Some(&decl.modifiers),
|
||||
Declaration::TSModuleDeclaration(decl) => Some(&decl.modifiers),
|
||||
Declaration::TSInterfaceDeclaration(decl) => Some(&decl.modifiers),
|
||||
_ => None,
|
||||
Declaration::VariableDeclaration(decl) => decl.declare,
|
||||
Declaration::FunctionDeclaration(decl) => decl.modifiers.is_contains_declare(),
|
||||
Declaration::ClassDeclaration(decl) => decl.modifiers.is_contains_declare(),
|
||||
Declaration::TSEnumDeclaration(decl) => decl.modifiers.is_contains_declare(),
|
||||
Declaration::TSTypeAliasDeclaration(decl) => decl.modifiers.is_contains_declare(),
|
||||
Declaration::TSModuleDeclaration(decl) => decl.modifiers.is_contains_declare(),
|
||||
Declaration::TSInterfaceDeclaration(decl) => decl.modifiers.is_contains_declare(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VariableDeclaration<'a> {
|
||||
pub fn is_typescript_syntax(&self) -> bool {
|
||||
self.modifiers.contains(ModifierKind::Declare)
|
||||
self.declare
|
||||
}
|
||||
|
||||
pub fn has_init(&self) -> bool {
|
||||
|
|
|
|||
|
|
@ -6,13 +6,14 @@
|
|||
// NB: `#[visited_node]` attribute on AST nodes does not do anything to the code in this file.
|
||||
// It is purely a marker for codegen used in `oxc_traverse`. See docs in that crate.
|
||||
|
||||
use crate::ast::*;
|
||||
|
||||
use std::{cell::Cell, hash::Hash};
|
||||
|
||||
use oxc_allocator::Vec;
|
||||
use oxc_span::{Atom, GetSpan, Span};
|
||||
|
||||
use crate::ast::Modifiers;
|
||||
use crate::ast::*;
|
||||
|
||||
impl<'a> TSEnumDeclaration<'a> {
|
||||
pub fn new(
|
||||
span: Span,
|
||||
|
|
@ -198,68 +199,6 @@ impl<'a> Decorator<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl ModifierKind {
|
||||
pub fn is_typescript_syntax(&self) -> bool {
|
||||
!matches!(self, Self::Async | Self::Default | Self::Export | Self::Static)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Modifiers<'a> {
|
||||
pub fn new(modifiers: Vec<'a, Modifier>) -> Self {
|
||||
Self(Some(modifiers))
|
||||
}
|
||||
|
||||
pub fn empty() -> Self {
|
||||
Self(None)
|
||||
}
|
||||
|
||||
pub fn is_none(&self) -> bool {
|
||||
self.0.is_none()
|
||||
}
|
||||
|
||||
pub fn contains(&self, target: ModifierKind) -> bool {
|
||||
self.0
|
||||
.as_ref()
|
||||
.map_or(false, |modifiers| modifiers.iter().any(|modifier| modifier.kind == target))
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = &Modifier> + '_ {
|
||||
self.0.as_ref().into_iter().flat_map(|modifiers| modifiers.iter())
|
||||
}
|
||||
|
||||
/// Find a modifier by kind
|
||||
pub fn find(&self, kind: ModifierKind) -> Option<&Modifier> {
|
||||
self.find_where(|modifier| modifier.kind == kind)
|
||||
}
|
||||
|
||||
pub fn find_where<F>(&self, f: F) -> Option<&Modifier>
|
||||
where
|
||||
F: Fn(&Modifier) -> bool,
|
||||
{
|
||||
self.0.as_ref().and_then(|modifiers| modifiers.iter().find(|modifier| f(modifier)))
|
||||
}
|
||||
|
||||
pub fn is_contains_declare(&self) -> bool {
|
||||
self.contains(ModifierKind::Declare)
|
||||
}
|
||||
|
||||
pub fn is_contains_abstract(&self) -> bool {
|
||||
self.contains(ModifierKind::Abstract)
|
||||
}
|
||||
|
||||
pub fn remove_type_modifiers(&mut self) {
|
||||
if let Some(list) = &mut self.0 {
|
||||
list.retain(|m| !m.kind.is_typescript_syntax());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_modifier(&mut self, modifier: Modifier) {
|
||||
if let Some(list) = self.0.as_mut() {
|
||||
list.push(modifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ImportOrExportKind {
|
||||
pub fn is_value(&self) -> bool {
|
||||
matches!(self, Self::Value)
|
||||
|
|
|
|||
|
|
@ -580,7 +580,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for UsingDeclaration<'a> {
|
|||
impl<'a, const MINIFY: bool> Gen<MINIFY> for VariableDeclaration<'a> {
|
||||
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
|
||||
p.add_source_mapping(self.span.start);
|
||||
if self.modifiers.is_contains_declare() {
|
||||
if self.declare {
|
||||
p.print_str(b"declare ");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
|||
decl: &VariableDeclaration<'a>,
|
||||
check_binding: bool,
|
||||
) -> Option<Box<'a, VariableDeclaration<'a>>> {
|
||||
if decl.modifiers.is_contains_declare() {
|
||||
if decl.declare {
|
||||
None
|
||||
} else {
|
||||
let declarations =
|
||||
|
|
@ -39,7 +39,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
|||
decl.span,
|
||||
decl.kind,
|
||||
self.ast.new_vec_from_iter(declarations),
|
||||
self.modifiers_declare(),
|
||||
self.modifiers_declare().is_contains_declare(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +126,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
|||
decl.span,
|
||||
VariableDeclarationKind::Const,
|
||||
declarations,
|
||||
self.modifiers_declare(),
|
||||
self.modifiers_declare().is_contains_declare(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
|||
span: SPAN,
|
||||
kind,
|
||||
declarations,
|
||||
modifiers: self.modifiers_declare(),
|
||||
declare: self.modifiers_declare().is_contains_declare(),
|
||||
}),
|
||||
ExportDefaultDeclarationKind::from(
|
||||
self.ast.identifier_reference_expression(
|
||||
|
|
|
|||
|
|
@ -408,3 +408,11 @@ pub fn jsx_element_no_match(span0: Span, span1: Span, name: &str) -> OxcDiagnost
|
|||
OxcDiagnostic::error(format!("Expected corresponding JSX closing tag for '{name}'."))
|
||||
.with_labels([span0.into(), span1.into()])
|
||||
}
|
||||
|
||||
#[cold]
|
||||
pub fn modifiers_cannot_appear(span: Span, name: &str) -> OxcDiagnostic {
|
||||
OxcDiagnostic::error(format!(
|
||||
"TS1044: '{name}' modifier cannot appear on a module or namespace element."
|
||||
))
|
||||
.with_label(span)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ impl<'a> ParserImpl<'a> {
|
|||
&mut self,
|
||||
start_span: Span,
|
||||
decl_ctx: VariableDeclarationContext,
|
||||
modifiers: Modifiers<'a>,
|
||||
modifiers: &Modifiers<'a>,
|
||||
) -> Result<Box<'a, VariableDeclaration<'a>>> {
|
||||
let kind = match self.cur_kind() {
|
||||
Kind::Var => VariableDeclarationKind::Var,
|
||||
|
|
@ -67,7 +67,21 @@ impl<'a> ParserImpl<'a> {
|
|||
self.asi()?;
|
||||
}
|
||||
|
||||
Ok(self.ast.variable_declaration(self.end_span(start_span), kind, declarations, modifiers))
|
||||
for modifier in modifiers.iter() {
|
||||
if modifier.kind != ModifierKind::Declare {
|
||||
self.error(diagnostics::modifiers_cannot_appear(
|
||||
modifier.span,
|
||||
modifier.kind.as_str(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(self.ast.variable_declaration(
|
||||
self.end_span(start_span),
|
||||
kind,
|
||||
declarations,
|
||||
modifiers.is_contains_declare(),
|
||||
))
|
||||
}
|
||||
|
||||
fn parse_variable_declarator(
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ impl<'a> ParserImpl<'a> {
|
|||
let decl = self.parse_variable_declaration(
|
||||
start_span,
|
||||
VariableDeclarationContext::new(VariableDeclarationParent::Statement),
|
||||
Modifiers::empty(),
|
||||
&Modifiers::empty(),
|
||||
)?;
|
||||
|
||||
if stmt_ctx.is_single_statement() && decl.kind.is_lexical() {
|
||||
|
|
@ -287,7 +287,7 @@ impl<'a> ParserImpl<'a> {
|
|||
let start_span = self.start_span();
|
||||
let init_declaration = self.context(Context::empty(), Context::In, |p| {
|
||||
let decl_ctx = VariableDeclarationContext::new(VariableDeclarationParent::For);
|
||||
p.parse_variable_declaration(start_span, decl_ctx, Modifiers::empty())
|
||||
p.parse_variable_declaration(start_span, decl_ctx, &Modifiers::empty())
|
||||
})?;
|
||||
|
||||
// for (.. a in) for (.. a of)
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ impl<'a> ParserImpl<'a> {
|
|||
.parse_variable_declaration(
|
||||
start_span,
|
||||
VariableDeclarationContext::new(VariableDeclarationParent::Clause),
|
||||
modifiers,
|
||||
&modifiers,
|
||||
)
|
||||
.map(Declaration::VariableDeclaration),
|
||||
_ if self.at_function_with_async() => {
|
||||
|
|
|
|||
|
|
@ -94,7 +94,6 @@ pub fn check<'a>(node: &AstNode<'a>, ctx: &SemanticBuilder<'a>) {
|
|||
AstKind::ObjectExpression(expr) => js::check_object_expression(expr, ctx),
|
||||
AstKind::UnaryExpression(expr) => js::check_unary_expression(expr, node, ctx),
|
||||
AstKind::YieldExpression(expr) => js::check_yield_expression(expr, node, ctx),
|
||||
AstKind::VariableDeclaration(decl) => ts::check_variable_declaration(decl, node, ctx),
|
||||
AstKind::VariableDeclarator(decl) => ts::check_variable_declarator(decl, ctx),
|
||||
AstKind::SimpleAssignmentTarget(target) => ts::check_simple_assignment_target(target, ctx),
|
||||
AstKind::TSTypeParameterDeclaration(declaration) => {
|
||||
|
|
|
|||
|
|
@ -172,13 +172,6 @@ fn check_declaration_modifiers<'a>(
|
|||
}
|
||||
}
|
||||
}
|
||||
pub fn check_variable_declaration<'a>(
|
||||
decl: &VariableDeclaration<'a>,
|
||||
node: &AstNode<'a>,
|
||||
ctx: &SemanticBuilder<'a>,
|
||||
) {
|
||||
check_declaration_modifiers(&decl.modifiers, node, ctx);
|
||||
}
|
||||
|
||||
pub fn check_function<'a>(function: &Function<'a>, node: &AstNode<'a>, ctx: &SemanticBuilder<'a>) {
|
||||
check_declaration_modifiers(&function.modifiers, node, ctx);
|
||||
|
|
|
|||
|
|
@ -114,20 +114,3 @@ fn test_export_flag() {
|
|||
tester.has_root_symbol("b").contains_flags(SymbolFlags::Export).test();
|
||||
tester.has_root_symbol("c").contains_flags(SymbolFlags::Export).test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_modifiers() {
|
||||
const PARAM_PROPERTY: &str =
|
||||
"A parameter property is only allowed in a constructor implementation.";
|
||||
const ILLEGAL_MODIFIER: &str = "Modifiers cannot be used here.";
|
||||
const READONLY: &str =
|
||||
"'readonly' modifier can only appear on a property declaration or index signature.";
|
||||
|
||||
SemanticTester::ts("function foo(public x: number) { }").has_error(PARAM_PROPERTY);
|
||||
// SemanticTester::ts("function foo() { export const x = 1; }").has_error(illegal_modifier);
|
||||
SemanticTester::ts("function foo() { public const x = 1; }").has_error(ILLEGAL_MODIFIER);
|
||||
SemanticTester::ts("function foo() { private const x = 1; }").has_error(ILLEGAL_MODIFIER);
|
||||
SemanticTester::ts("function foo() { protected const x = 1; }").has_error(ILLEGAL_MODIFIER);
|
||||
SemanticTester::ts("function foo() { abstract const x = 1; }").has_error(ILLEGAL_MODIFIER);
|
||||
SemanticTester::ts("function foo() { readonly const x = 1; }").has_error(READONLY);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ impl<'a> ArrowFunctions<'a> {
|
|||
SPAN,
|
||||
VariableDeclarationKind::Var,
|
||||
self.ctx.ast.new_vec_single(variable_declarator),
|
||||
Modifiers::empty(),
|
||||
false,
|
||||
);
|
||||
|
||||
let stmt = Statement::VariableDeclaration(stmt);
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ impl<'a> ModuleImports<'a> {
|
|||
let decl = self.ast.variable_declarator(SPAN, var_kind, id, Some(init), false);
|
||||
self.ast.new_vec_single(decl)
|
||||
};
|
||||
let var_decl = self.ast.variable_declaration(SPAN, var_kind, decl, Modifiers::empty());
|
||||
let var_decl = self.ast.variable_declaration(SPAN, var_kind, decl, false);
|
||||
Statement::VariableDeclaration(var_decl)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ impl<'a> ReactJsxSource<'a> {
|
|||
let decl = self.ctx.ast.variable_declarator(SPAN, var_kind, id, Some(init), false);
|
||||
self.ctx.ast.new_vec_single(decl)
|
||||
};
|
||||
let var_decl = self.ctx.ast.variable_declaration(SPAN, var_kind, decl, Modifiers::empty());
|
||||
let var_decl = self.ctx.ast.variable_declaration(SPAN, var_kind, decl, false);
|
||||
Some(Statement::VariableDeclaration(var_decl))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -311,13 +311,15 @@ impl<'a> TypeScriptAnnotations<'a> {
|
|||
|
||||
pub fn transform_statements(&mut self, stmts: &mut ArenaVec<'a, Statement<'a>>) {
|
||||
// Remove declare declaration
|
||||
stmts.retain(|stmt| {
|
||||
if let Some(decl) = stmt.as_declaration() {
|
||||
decl.modifiers().map_or(true, |m| !m.is_contains_declare())
|
||||
} else {
|
||||
true
|
||||
}
|
||||
});
|
||||
stmts.retain(
|
||||
|stmt| {
|
||||
if let Some(decl) = stmt.as_declaration() {
|
||||
!decl.declare()
|
||||
} else {
|
||||
true
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
pub fn transform_statements_on_exit(
|
||||
|
|
|
|||
|
|
@ -134,8 +134,7 @@ impl<'a> TypeScriptEnum<'a> {
|
|||
decls.push(decl);
|
||||
decls
|
||||
};
|
||||
let variable_declaration =
|
||||
self.ctx.ast.variable_declaration(span, kind, decls, Modifiers::empty());
|
||||
let variable_declaration = self.ctx.ast.variable_declaration(span, kind, decls, false);
|
||||
let variable_declaration = Declaration::VariableDeclaration(variable_declaration);
|
||||
|
||||
let stmt = if is_export {
|
||||
|
|
|
|||
|
|
@ -66,8 +66,7 @@ impl<'a> TypeScript<'a> {
|
|||
false,
|
||||
))
|
||||
};
|
||||
let variable_declaration =
|
||||
self.ctx.ast.variable_declaration(SPAN, kind, decls, Modifiers::empty());
|
||||
let variable_declaration = self.ctx.ast.variable_declaration(SPAN, kind, decls, false);
|
||||
|
||||
Declaration::VariableDeclaration(variable_declaration)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ impl<'a> TypeScript<'a> {
|
|||
// legal syntax in TS namespaces
|
||||
let export_decl = export_decl.unbox();
|
||||
if let Some(decl) = export_decl.declaration {
|
||||
if decl.modifiers().is_some_and(Modifiers::is_contains_declare) {
|
||||
if decl.declare() {
|
||||
continue;
|
||||
}
|
||||
match decl {
|
||||
|
|
@ -290,7 +290,7 @@ impl<'a> TypeScript<'a> {
|
|||
SPAN,
|
||||
kind,
|
||||
declarations,
|
||||
Modifiers::empty(),
|
||||
false,
|
||||
))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3835,8 +3835,8 @@ pub(crate) const OFFSET_VARIABLE_DECLARATION_SPAN: usize = offset_of!(VariableDe
|
|||
pub(crate) const OFFSET_VARIABLE_DECLARATION_KIND: usize = offset_of!(VariableDeclaration, kind);
|
||||
pub(crate) const OFFSET_VARIABLE_DECLARATION_DECLARATIONS: usize =
|
||||
offset_of!(VariableDeclaration, declarations);
|
||||
pub(crate) const OFFSET_VARIABLE_DECLARATION_MODIFIERS: usize =
|
||||
offset_of!(VariableDeclaration, modifiers);
|
||||
pub(crate) const OFFSET_VARIABLE_DECLARATION_DECLARE: usize =
|
||||
offset_of!(VariableDeclaration, declare);
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug)]
|
||||
|
|
@ -3857,11 +3857,8 @@ impl<'a> VariableDeclarationWithoutDeclarations<'a> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn modifiers(&self) -> &Modifiers<'a> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_VARIABLE_DECLARATION_MODIFIERS)
|
||||
as *const Modifiers<'a>)
|
||||
}
|
||||
pub fn declare(&self) -> &bool {
|
||||
unsafe { &*((self.0 as *const u8).add(OFFSET_VARIABLE_DECLARATION_DECLARE) as *const bool) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6414,7 +6414,7 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
|
|||
· ╰── `from` expected
|
||||
╰────
|
||||
|
||||
× Modifiers cannot be used here.
|
||||
× TS1044: 'export' modifier cannot appear on a module or namespace element.
|
||||
╭─[compiler/exportAlreadySeen.ts:2:12]
|
||||
1 │ module M {
|
||||
2 │ export export var x = 1;
|
||||
|
|
@ -6422,6 +6422,14 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
|
|||
3 │ export export function f() { }
|
||||
╰────
|
||||
|
||||
× TS1044: 'export' modifier cannot appear on a module or namespace element.
|
||||
╭─[compiler/exportAlreadySeen.ts:12:12]
|
||||
11 │ declare module A {
|
||||
12 │ export export var x;
|
||||
· ──────
|
||||
13 │ export export function f()
|
||||
╰────
|
||||
|
||||
× Modifiers cannot be used here.
|
||||
╭─[compiler/exportAlreadySeen.ts:3:12]
|
||||
2 │ export export var x = 1;
|
||||
|
|
@ -6454,14 +6462,6 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
|
|||
6 │ export export class C { }
|
||||
╰────
|
||||
|
||||
× Modifiers cannot be used here.
|
||||
╭─[compiler/exportAlreadySeen.ts:12:12]
|
||||
11 │ declare module A {
|
||||
12 │ export export var x;
|
||||
· ──────
|
||||
13 │ export export function f()
|
||||
╰────
|
||||
|
||||
× Modifiers cannot be used here.
|
||||
╭─[compiler/exportAlreadySeen.ts:13:12]
|
||||
12 │ export export var x;
|
||||
|
|
@ -16373,7 +16373,7 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
|
|||
77 │ }
|
||||
╰────
|
||||
|
||||
× Modifiers cannot be used here.
|
||||
× TS1044: 'public' modifier cannot appear on a module or namespace element.
|
||||
╭─[conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts:4:5]
|
||||
3 │ module Y {
|
||||
4 │ public var x: number = 0;
|
||||
|
|
@ -16381,6 +16381,22 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
|
|||
5 │ }
|
||||
╰────
|
||||
|
||||
× TS1044: 'static' modifier cannot appear on a module or namespace element.
|
||||
╭─[conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts:12:5]
|
||||
11 │ module Y4 {
|
||||
12 │ static var x: number = 0;
|
||||
· ──────
|
||||
13 │ }
|
||||
╰────
|
||||
|
||||
× TS1044: 'private' modifier cannot appear on a module or namespace element.
|
||||
╭─[conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts:20:5]
|
||||
19 │ module YY2 {
|
||||
20 │ private var x: number = 0;
|
||||
· ───────
|
||||
21 │ }
|
||||
╰────
|
||||
|
||||
× Modifiers cannot be used here.
|
||||
╭─[conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts:8:5]
|
||||
7 │ module Y2 {
|
||||
|
|
@ -16389,14 +16405,6 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
|
|||
9 │ }
|
||||
╰────
|
||||
|
||||
× Modifiers cannot be used here.
|
||||
╭─[conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts:12:5]
|
||||
11 │ module Y4 {
|
||||
12 │ static var x: number = 0;
|
||||
· ──────
|
||||
13 │ }
|
||||
╰────
|
||||
|
||||
× Modifiers cannot be used here.
|
||||
╭─[conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts:16:5]
|
||||
15 │ module YY {
|
||||
|
|
@ -16405,14 +16413,6 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
|
|||
17 │ }
|
||||
╰────
|
||||
|
||||
× Modifiers cannot be used here.
|
||||
╭─[conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts:20:5]
|
||||
19 │ module YY2 {
|
||||
20 │ private var x: number = 0;
|
||||
· ───────
|
||||
21 │ }
|
||||
╰────
|
||||
|
||||
× Modifiers cannot be used here.
|
||||
╭─[conformance/internalModules/moduleBody/invalidModuleWithVarStatements.ts:25:5]
|
||||
24 │ module YY3 {
|
||||
|
|
|
|||
Loading…
Reference in a new issue