mirror of
https://github.com/swc-project/swc.git
synced 2024-12-24 14:16:12 +03:00
fix(es/parser): Parse decorators after export
(#7340)
This commit is contained in:
parent
b80ceaed03
commit
985f0cad06
25
crates/swc/tests/fixture/issues-6xxx/6984/1/input/.swcrc
Normal file
25
crates/swc/tests/fixture/issues-6xxx/6984/1/input/.swcrc
Normal 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
|
||||
}
|
||||
}
|
12
crates/swc/tests/fixture/issues-6xxx/6984/1/input/index.js
Normal file
12
crates/swc/tests/fixture/issues-6xxx/6984/1/input/index.js
Normal 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>
|
||||
}
|
||||
}
|
30
crates/swc/tests/fixture/issues-6xxx/6984/1/output/index.js
Normal file
30
crates/swc/tests/fixture/issues-6xxx/6984/1/output/index.js
Normal 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 };
|
@ -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()
|
||||
}
|
||||
|
@ -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)?
|
||||
|
@ -0,0 +1,4 @@
|
||||
// @filename: file3.js
|
||||
|
||||
// error
|
||||
export @dec default class C3 {}
|
@ -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 {}
|
||||
: ^^^^^^^
|
||||
`----
|
@ -0,0 +1,5 @@
|
||||
// @filename: file6.js
|
||||
|
||||
// error
|
||||
@dec export @dec class C6 {}
|
||||
|
@ -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 {}
|
||||
: ^^^^
|
||||
`----
|
@ -0,0 +1,4 @@
|
||||
// @filename: file7.js
|
||||
|
||||
// error
|
||||
@dec export default @dec class C7 {}
|
@ -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 {}
|
||||
: ^^^^
|
||||
`----
|
@ -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 };
|
||||
|
Loading…
Reference in New Issue
Block a user