fix(es/parser): Parse decorators after export (#7340)

This commit is contained in:
magic-akari 2023-04-29 21:26:13 +08:00 committed by GitHub
parent b80ceaed03
commit 985f0cad06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 130 additions and 2 deletions

View File

@ -0,0 +1,25 @@
{
"jsc": {
"externalHelpers": true,
"parser": {
"syntax": "ecmascript",
"jsx": true,
"decorators": true,
"dynamicImport": true,
"decoratorsBeforeExport": true
},
"transform": {
"legacyDecorator": true,
"decoratorMetadata": true
},
"minify": {
"compress": false
}
},
"isModule": "unknown",
"env": {
"mode": "usage",
"coreJs": "3",
"dynamicImport": true
}
}

View File

@ -0,0 +1,12 @@
import React from 'react'
import { withRouter } from 'react-router-dom'
export default
@withRouter
class App extends React.Component {
render() {
console.log(this.props)
return <div>134</div>
}
}

View File

@ -0,0 +1,30 @@
import { _ as _class_call_check } from "@swc/helpers/_/_class_call_check";
import { _ as _create_class } from "@swc/helpers/_/_create_class";
import { _ as _inherits } from "@swc/helpers/_/_inherits";
import { _ as _create_super } from "@swc/helpers/_/_create_super";
import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
import React from "react";
import { withRouter } from "react-router-dom";
var App = function(_React_Component) {
"use strict";
_inherits(App, _React_Component);
var _super = _create_super(App);
function App() {
_class_call_check(this, App);
return _super.apply(this, arguments);
}
_create_class(App, [
{
key: "render",
value: function render() {
console.log(this.props);
return React.createElement("div", null, "134");
}
}
]);
return App;
}(React.Component);
App = _ts_decorate([
withRouter
], App);
export { App as default };

View File

@ -270,6 +270,7 @@ pub enum SyntaxError {
TS2499,
TS2703,
TS4112,
TS8038,
TSTypeAnnotationAfterAssign,
TsNonNullAssertionNotAllowed(JsWord),
@ -691,6 +692,9 @@ impl SyntaxError {
SyntaxError::TS4112 => "This member cannot have an 'override' modifier because its \
containing class does not extend another class."
.into(),
SyntaxError::TS8038 => "Decorators may not appear after `export` or `export default` \
if they also appear before `export`."
.into(),
SyntaxError::TSTypeAnnotationAfterAssign => {
"Type annotations must come before default assignments".into()
}

View File

@ -327,7 +327,7 @@ impl<I: Tokens> Parser<I> {
Ok(self.with_ctx(ctx).parse_binding_ident()?.id)
}
fn parse_export(&mut self, decorators: Vec<Decorator>) -> PResult<ModuleDecl> {
fn parse_export(&mut self, mut decorators: Vec<Decorator>) -> PResult<ModuleDecl> {
if !self.ctx().module {
// Switch to module mode
let ctx = Context {
@ -417,6 +417,17 @@ impl<I: Tokens> Parser<I> {
let mut export_default = None;
if !type_only && eat!(self, "default") {
if is!(self, '@') {
let start = cur_pos!(self);
let after_decorators = self.parse_decorators(false)?;
if !decorators.is_empty() {
syntax_error!(self, span!(self, start), SyntaxError::TS8038);
}
decorators = after_decorators;
}
if self.input.syntax().typescript() {
if is!(self, "abstract")
&& peeked_is!(self, "class")
@ -477,6 +488,17 @@ impl<I: Tokens> Parser<I> {
}
}
if is!(self, '@') {
let start = cur_pos!(self);
let after_decorators = self.parse_decorators(false)?;
if !decorators.is_empty() {
syntax_error!(self, span!(self, start), SyntaxError::TS8038);
}
decorators = after_decorators;
}
let decl = if !type_only && is!(self, "class") {
let class_start = cur_pos!(self);
self.parse_class_decl(start, class_start, decorators, false)?

View File

@ -0,0 +1,4 @@
// @filename: file3.js
// error
export @dec default class C3 {}

View File

@ -0,0 +1,7 @@
x Expected '{', got 'default'
,-[$DIR/tests/typescript-errors/esDecorators/classDeclaration/esDecorators-classDeclaration-exportModifier/file3.ts:3:1]
3 | // error
4 | export @dec default class C3 {}
: ^^^^^^^
`----

View File

@ -0,0 +1,5 @@
// @filename: file6.js
// error
@dec export @dec class C6 {}

View File

@ -0,0 +1,7 @@
x Decorators may not appear after `export` or `export default` if they also appear before `export`.
,-[$DIR/tests/typescript-errors/esDecorators/classDeclaration/esDecorators-classDeclaration-exportModifier/file6.ts:3:1]
3 | // error
4 | @dec export @dec class C6 {}
: ^^^^
`----

View File

@ -0,0 +1,4 @@
// @filename: file7.js
// error
@dec export default @dec class C7 {}

View File

@ -0,0 +1,7 @@
x Decorators may not appear after `export` or `export default` if they also appear before `export`.
,-[$DIR/tests/typescript-errors/esDecorators/classDeclaration/esDecorators-classDeclaration-exportModifier/file7.ts:3:1]
3 | // error
4 | @dec export default @dec class C7 {}
: ^^^^
`----

View File

@ -1,4 +1,4 @@
export default class A {
let A = class A {
};
A = _ts_decorate([
dec
@ -8,3 +8,4 @@ let B = class B {
B = _ts_decorate([
dec
], B);
export { A as default };