Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 34 additions & 44 deletions crates/swc/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,16 +295,42 @@ impl Options {

let mut transform = transform.into_inner().unwrap_or_default();

// Do a resolver pass before everything.
//
// We do this before creating custom passes, so custom passses can use the
// variable management system based on the syntax contexts.
if syntax.typescript() {
assumptions.set_class_methods |= !transform.use_define_for_class_fields.into_bool();
}

assumptions.set_public_class_fields |= !transform.use_define_for_class_fields.into_bool();

// Do a resolver pass before everything.
//
// We do this before creating custom passes, so custom passses can use the
// variable management system based on the syntax contexts.
//
// Exception: Classic JSX transformation runs before the resolver
// because it's a context-free syntactic transformation that doesn't require
// scope information.
// Running resolver first would mark identifiers (like JSX pragma functions)
// with syntax contexts, making it harder for the JSX transform to
// handle pragma references that should resolve to local scope declarations.

let jsx_pass = 'jsx_pass: {
if !syntax.jsx() {
break 'jsx_pass None;
}

let (mut before_resolver, after_resolver) = react::react(
cm.clone(),
comments.cloned(),
transform.react,
top_level_mark,
unresolved_mark,
);

program.mutate(&mut before_resolver);

Some(after_resolver)
};

program.visit_mut_with(&mut resolver(
unresolved_mark,
top_level_mark,
Expand Down Expand Up @@ -780,53 +806,17 @@ impl Options {
..Default::default()
};

(
Optional::new(
typescript::typescript(ts_config, unresolved_mark, top_level_mark),
syntax.typescript() && !syntax.jsx(),
),
// [TODO]: Remove tsx
Optional::new(
{
let (pragma, pragma_frag) = match transform.react.runtime {
react::Runtime::Classic(ref config) => (
Some(config.pragma.clone()),
Some(config.pragma_frag.clone()),
),
_ => (None, None),
};

typescript::tsx::<Option<&dyn Comments>>(
cm.clone(),
ts_config,
typescript::TsxConfig {
pragma,
pragma_frag,
},
comments.map(|v| v as _),
unresolved_mark,
top_level_mark,
)
},
syntax.typescript() && syntax.jsx(),
),
Optional::new(
typescript::typescript(ts_config, unresolved_mark, top_level_mark),
syntax.typescript(),
)
},
),
(
plugin_transforms.take(),
custom_before_pass(&program),
// handle jsx
Optional::new(
react::react(
cm.clone(),
comments.cloned(),
transform.react,
top_level_mark,
unresolved_mark,
),
syntax.jsx(),
),
jsx_pass,
built_pass,
Optional::new(jest::jest(), transform.hidden.jest.into_bool()),
Optional::new(
Expand Down
25 changes: 25 additions & 0 deletions crates/swc/tests/fixture/issues-10xxx/10553/input/.swcrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"jsc": {
"parser": {
"syntax": "ecmascript",
"exportDefaultFrom": true,
"jsx": true
},
"target": "es5",
"loose": false,
"minify": {
"compress": false,
"mangle": false
},
"transform": {
"react": {
"runtime": "classic"
}
}
},
"module": {
"type": "es6"
},
"minify": false,
"isModule": true
}
3 changes: 3 additions & 0 deletions crates/swc/tests/fixture/issues-10xxx/10553/input/input.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function Home(React) {
return <div>Hello World {count}</div>
}
3 changes: 3 additions & 0 deletions crates/swc/tests/fixture/issues-10xxx/10553/output/input.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function Home(React) {
return React.createElement("div", null, "Hello World ", count);
}
7 changes: 6 additions & 1 deletion crates/swc/tests/fixture/issues-2xxx/2214/input/.swcrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
"parser": {
"syntax": "typescript",
"tsx": true
},
"transform": {
"react": {
"runtime": "classic"
}
}
}
}
}
5 changes: 1 addition & 4 deletions crates/swc/tests/fixture/issues-2xxx/2214/output/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { jsx as _jsx } from "react/jsx-runtime";
import React from "react";
(function(Test) {
Test.content = /*#__PURE__*/ _jsx("div", {
children: "Content"
});
Test.content = /*#__PURE__*/ React.createElement("div", null, "Content");
})(Test || (Test = {}));
export var Test;
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
//// [file.tsx]
//! x Import assignment cannot be used when targeting ECMAScript modules. Consider using `import * as ns from "mod"`, `import {a} from "mod"`, `import d from "mod"`, or another module format instead.
//! ,-[2:1]
//! 1 |
//! 2 | import React = require('react');
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//! 3 |
//! 4 | interface Prop {
//! 5 | a: number,
//! `----
function Comp(p) {
return <div>{p.b}</div>;
}
// OK
var k = <Comp a={10} b="hi" children="lol"/>;
var k1 = <Comp a={10} b="hi">
hi hi hi!
</Comp>;
var k2 = <Comp a={10} b="hi">
<div>hi hi hi!</div>
</Comp>;
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
//// [file.tsx]
//! x Import assignment cannot be used when targeting ECMAScript modules. Consider using `import * as ns from "mod"`, `import {a} from "mod"`, `import d from "mod"`, or another module format instead.
//! ,-[2:1]
//! 1 |
//! 2 | import React = require('react');
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//! 3 |
//! 4 | interface Prop {
//! 5 | a: number,
//! `----
function Comp(p) {
return <div>{p.b}</div>;
}
<Comp a={10} b="hi" children="lol"/>, <Comp a={10} b="hi">
hi hi hi!
</Comp>, <Comp a={10} b="hi">
<div>hi hi hi!</div>
</Comp>;
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
//// [file.tsx]
//! x Import assignment cannot be used when targeting ECMAScript modules. Consider using `import * as ns from "mod"`, `import {a} from "mod"`, `import d from "mod"`, or another module format instead.
//! ,-[2:1]
//! 1 |
//! 2 | import React = require('react');
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//! 3 |
//! 4 | const Tag = (x: {}) => <div></div>;
//! `----
var Tag = function(x) {
return <div></div>;
};
// OK
var k1 = <Tag/>;
var k2 = <Tag></Tag>;
// Not OK (excess children)
var k3 = <Tag children={<div></div>}/>;
var k4 = <Tag key="1"><div></div></Tag>;
var k5 = <Tag key="1"><div></div><div></div></Tag>;
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
//// [file.tsx]
//! x Import assignment cannot be used when targeting ECMAScript modules. Consider using `import * as ns from "mod"`, `import {a} from "mod"`, `import d from "mod"`, or another module format instead.
//! ,-[2:1]
//! 1 |
//! 2 | import React = require('react');
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//! 3 |
//! 4 | const Tag = (x: {}) => <div></div>;
//! `----
var Tag = function(x) {
return <div></div>;
};
<Tag/>, <Tag></Tag>, <Tag children={<div></div>}/>, <Tag key="1"><div></div></Tag>, <Tag key="1"><div></div><div></div></Tag>;
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
//// [checkJsxChildrenProperty16.tsx]
//! x Import assignment cannot be used when targeting ECMAScript modules. Consider using `import * as ns from "mod"`, `import {a} from "mod"`, `import d from "mod"`, or another module format instead.
//! ,-[6:1]
//! 3 |
//! 4 | // repro from #53493
//! 5 |
//! 6 | import React = require('react');
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//! 7 |
//! 8 | export type Props =
//! 9 | | { renderNumber?: false; children: (arg: string) => void }
//! `----
/// <reference path="/.lib/react16.d.ts" />
// repro from #53493
export var Test = function() {
return <>
<Foo>{function(value) {}}</Foo>
<Foo renderNumber>{function(value) {}}</Foo>

<Foo children={function(value) {}}/>
<Foo renderNumber children={function(value) {}}/>
</>;
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
//// [checkJsxChildrenProperty16.tsx]
//! x Import assignment cannot be used when targeting ECMAScript modules. Consider using `import * as ns from "mod"`, `import {a} from "mod"`, `import d from "mod"`, or another module format instead.
//! ,-[6:1]
//! 3 |
//! 4 | // repro from #53493
//! 5 |
//! 6 | import React = require('react');
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//! 7 |
//! 8 | export type Props =
//! 9 | | { renderNumber?: false; children: (arg: string) => void }
//! `----
export var Test = function() {
return <>
<Foo>{function(value) {}}</Foo>
<Foo renderNumber>{function(value) {}}</Foo>

<Foo children={function(value) {}}/>
<Foo renderNumber children={function(value) {}}/>
</>;
};
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
//// [file.tsx]
//! x Import assignment cannot be used when targeting ECMAScript modules. Consider using `import * as ns from "mod"`, `import {a} from "mod"`, `import d from "mod"`, or another module format instead.
//! ,-[2:1]
//! 1 |
//! 2 | import React = require('react');
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//! 3 |
//! 4 | interface Prop {
//! 5 | a: number,
//! `----
function Comp(p) {
return <div>{p.b}</div>;
}
// Error: missing children
var k = <Comp a={10} b="hi"/>;
var k0 = <Comp a={10} b="hi" children="Random">
hi hi hi!
</Comp>;
var o = {
children: "Random"
};
var k1 = <Comp a={10} b="hi" {...o}>
hi hi hi!
</Comp>;
// Error: incorrect type
var k2 = <Comp a={10} b="hi">
<div> My Div </div>
{function(name) {
return <div> My name {name} </div>;
}}
</Comp>;
var k3 = <Comp a={10} b="hi">
<div> My Div </div>
{1000000}
</Comp>;
var k4 = <Comp a={10} b="hi">
<div> My Div </div>
hi hi hi!
</Comp>;
var k5 = <Comp a={10} b="hi">
<div> My Div </div>
<div> My Div </div>
</Comp>;
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
//// [file.tsx]
//! x Import assignment cannot be used when targeting ECMAScript modules. Consider using `import * as ns from "mod"`, `import {a} from "mod"`, `import d from "mod"`, or another module format instead.
//! ,-[2:1]
//! 1 |
//! 2 | import React = require('react');
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//! 3 |
//! 4 | interface Prop {
//! 5 | a: number,
//! `----
function Comp(p) {
return <div>{p.b}</div>;
}
<Comp a={10} b="hi"/>, <Comp a={10} b="hi" children="Random">
hi hi hi!
</Comp>, <Comp a={10} b="hi" {...{
children: "Random"
}}>
hi hi hi!
</Comp>, <Comp a={10} b="hi">
<div> My Div </div>
{function(name) {
return <div> My name {name} </div>;
}}
</Comp>, <Comp a={10} b="hi">
<div> My Div </div>
{1000000}
</Comp>, <Comp a={10} b="hi">
<div> My Div </div>
hi hi hi!
</Comp>, <Comp a={10} b="hi">
<div> My Div </div>
<div> My Div </div>
</Comp>;
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
//// [file.tsx]
//! x Import assignment cannot be used when targeting ECMAScript modules. Consider using `import * as ns from "mod"`, `import {a} from "mod"`, `import d from "mod"`, or another module format instead.
//! ,-[2:1]
//! 1 |
//! 2 | import React = require('react');
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//! 3 |
//! 4 | // OK
//! 5 | let k1 = <div> <h2> Hello </h2> <h1> world </h1></div>;
//! `----
// OK
var k1 = <div> <h2> Hello </h2> <h1> world </h1></div>;
var k2 = <div> <h2> Hello </h2> {function(user) {
return <h2>{user.name}</h2>;
}}</div>;
var k3 = <div> {1} {"That is a number"} </div>;
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
//// [file.tsx]
//! x Import assignment cannot be used when targeting ECMAScript modules. Consider using `import * as ns from "mod"`, `import {a} from "mod"`, `import d from "mod"`, or another module format instead.
//! ,-[2:1]
//! 1 |
//! 2 | import React = require('react');
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//! 3 |
//! 4 | // OK
//! 5 | let k1 = <div> <h2> Hello </h2> <h1> world </h1></div>;
//! `----
<div> <h2> Hello </h2> <h1> world </h1></div>, <div> <h2> Hello </h2> {function(user) {
return <h2>{user.name}</h2>;
}}</div>, <div> {1} {"That is a number"} </div>;
Loading
Loading