Skip to content

Commit

Permalink
Merge branch 'main' into infer-extends
Browse files Browse the repository at this point in the history
  • Loading branch information
sosukesuzuki committed May 9, 2022
2 parents a965c3e + 871ed89 commit 828d3ad
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Makefile
@@ -1,5 +1,5 @@
FLOW_COMMIT = 92bbb5e9dacb8185aa73ea343954d0434b42c40b
TEST262_COMMIT = dcd25e616d1023922c3afb3fe13c792ed134f8f4
TEST262_COMMIT = 2e7cdfbe18eae4309677033673bb4b5ac6b1de40
TYPESCRIPT_COMMIT = b53073bf66571b4c99f0a93b8f76fb06b36d8991

# Fix color output until TravisCI fixes https://github.com/travis-ci/travis-ci/issues/7967
Expand Down
13 changes: 13 additions & 0 deletions packages/babel-generator/src/node/parentheses.ts
Expand Up @@ -5,6 +5,7 @@ import {
isAwaitExpression,
isBinary,
isBinaryExpression,
isUpdateExpression,
isCallExpression,
isClassDeclaration,
isClassExpression,
Expand All @@ -17,6 +18,7 @@ import {
isForInStatement,
isForOfStatement,
isForStatement,
isFunctionExpression,
isIfStatement,
isIndexedAccessType,
isIntersectionTypeAnnotation,
Expand Down Expand Up @@ -344,6 +346,16 @@ export function Identifier(
parent: t.Node,
printStack: Array<t.Node>,
): boolean {
// 13.15.2 AssignmentExpression RS: Evaluation
// (fn) = function () {};
if (
node.extra?.parenthesized &&
isAssignmentExpression(parent, { left: node }) &&
(isFunctionExpression(parent.right) || isClassExpression(parent.right)) &&
parent.right.id == null
) {
return true;
}
// Non-strict code allows the identifier `let`, but it cannot occur as-is in
// certain contexts to avoid ambiguity with contextual keyword `let`.
if (node.name === "let") {
Expand Down Expand Up @@ -414,6 +426,7 @@ function isFirstInContext(
if (
(hasPostfixPart(node, parent) && !isNewExpression(parent)) ||
(isSequenceExpression(parent) && parent.expressions[0] === node) ||
(isUpdateExpression(parent) && !parent.prefix) ||
isConditional(parent, { test: node }) ||
isBinary(parent, { left: node }) ||
isAssignmentExpression(parent, { left: node })
Expand Down
@@ -0,0 +1,7 @@
var f, g, h;
(f) = function () {};
(f) = class {};
g = function () {};
g = class {};
(h) = function noParen() {};
(h) = class noParen {}
@@ -0,0 +1,13 @@
var f, g, h;

(f) = function () {};

(f) = class {};

g = function () {};

g = class {};

h = function noParen() {};

h = class noParen {};
@@ -0,0 +1 @@
(function () { return {x: 24} }()).x++;
@@ -0,0 +1,5 @@
(function () {
return {
x: 24
};
})().x++;
Expand Up @@ -197,7 +197,7 @@ export default declare((api, options: Options) => {
current = current.parentPath;
jsxScope = HOISTED.get(current.node);
}
jsxScope ??= getHoistingScope(path.scope);
jsxScope ??= path.scope;

const visitorState: VisitorState = {
isImmutable: true,
Expand All @@ -212,7 +212,19 @@ export default declare((api, options: Options) => {
HOISTED.set(path.node, targetScope);

// Only hoist if it would give us an advantage.
if (targetScope === jsxScope) return;
for (let currentScope = jsxScope; ; ) {
if (targetScope === currentScope) return;
if (isHoistingScope(currentScope)) break;

currentScope = currentScope.parent;
if (!currentScope) {
throw new Error(
"Internal @babel/plugin-transform-react-constant-elements error: " +
"targetScope must be an ancestor of jsxScope. " +
"This is a Babel bug, please report it.",
);
}
}

const id = path.scope.generateUidBasedOnNode(name);
targetScope.push({ id: t.identifier(id) });
Expand Down
@@ -0,0 +1,12 @@
function RoutesComponent() {
return (
<Routes>
{(c) => {
{
const Component = c;
return <Component />;
}
}}
</Routes>
);
}
@@ -0,0 +1,10 @@
function RoutesComponent() {
return <Routes>
{c => {
{
const Component = c;
return <Component />;
}
}}
</Routes>;
}
24 changes: 14 additions & 10 deletions packages/babel-plugin-transform-react-jsx-self/src/index.ts
Expand Up @@ -14,6 +14,7 @@
*/
import { declare } from "@babel/helper-plugin-utils";
import { types as t } from "@babel/core";
import type { Visitor, NodePath } from "@babel/traverse";

const TRACE_ID = "__self";

Expand All @@ -23,14 +24,15 @@ const TRACE_ID = "__self";
*
* Derived from `Scope#getFunctionParent`
*/
function getThisFunctionParent(path) {
function getThisFunctionParent(
path: NodePath<t.JSXOpeningElement>,
): NodePath<Exclude<t.FunctionParent, t.ArrowFunctionExpression>> | null {
let scope = path.scope;
do {
if (
scope.path.isFunctionParent() &&
!scope.path.isArrowFunctionExpression()
) {
return scope.path;
const { path } = scope;
if (path.isFunctionParent() && !path.isArrowFunctionExpression()) {
// @ts-expect-error TS does not exlucde ArrowFunctionExpression from FunctionParent
return path;
}
} while ((scope = scope.parent));
return null;
Expand All @@ -39,14 +41,14 @@ function getThisFunctionParent(path) {
/**
* Returns whether the class has specified a superclass.
*/
function isDerivedClass(classPath) {
function isDerivedClass(classPath: NodePath<t.Class>) {
return classPath.node.superClass !== null;
}

/**
* Returns whether `this` is allowed at given path.
*/
function isThisAllowed(path) {
function isThisAllowed(path: NodePath<t.JSXOpeningElement>) {
// This specifically skips arrow functions as they do not rewrite `this`.
const parentMethodOrFunction = getThisFunctionParent(path);
if (parentMethodOrFunction === null) {
Expand All @@ -63,13 +65,15 @@ function isThisAllowed(path) {
return true;
}
// Now we are in a constructor. If it is a derived class, we do not reference `this`.
return !isDerivedClass(parentMethodOrFunction.parentPath.parentPath);
return !isDerivedClass(
parentMethodOrFunction.parentPath.parentPath as NodePath<t.Class>,
);
}

export default declare(api => {
api.assertVersion(7);

const visitor = {
const visitor: Visitor = {
JSXOpeningElement(path) {
if (!isThisAllowed(path)) {
return;
Expand Down

0 comments on commit 828d3ad

Please sign in to comment.