Skip to content

Commit

Permalink
Transform updates to support Flow this annotation syntax (#25918)
Browse files Browse the repository at this point in the history
Flow introduced a new syntax to annotated the context type of a
function, this tries to update the rest and add 1 example usage.

- 2b1fb91 already added the changes
required for eslint.
- Jest transform is updated to use the recommended `hermes-parser` which
can parse current and Flow syntax and will be updated in the future.
- Rollup uses a new plugin to strip the flow types. This isn't ideal as
the npm module is deprecated in favor of using `hermes-parser`, but I
couldn't figure out how to integrate that with Rollup.
  • Loading branch information
kassens committed Jan 5, 2023
1 parent 2619886 commit b83baf6
Show file tree
Hide file tree
Showing 16 changed files with 95 additions and 8 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,13 @@
"fbjs-scripts": "1.2.0",
"filesize": "^6.0.1",
"flow-bin": "^0.190.0",
"flow-remove-types": "^2.196.1",
"glob": "^7.1.6",
"glob-stream": "^6.1.0",
"google-closure-compiler": "^20200517.0.0",
"gzip-size": "^5.1.1",
"hermes-eslint": "^0.9.0",
"hermes-parser": "^0.9.0",
"jasmine-check": "^1.0.0-rc.0",
"jest": "^26.6.3",
"jest-cli": "^26.6.3",
Expand Down
2 changes: 2 additions & 0 deletions packages/react-dom-bindings/src/shared/DOMNamespaces.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @noflow
*/

export const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @noflow
*/

const hasReadOnlyValue = {
Expand Down
2 changes: 2 additions & 0 deletions packages/react-dom-bindings/src/shared/assertValidProps.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @noflow
*/

import voidElementTags from './voidElementTags';
Expand Down
2 changes: 2 additions & 0 deletions packages/react-dom/src/test-utils/ReactTestUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @noflow
*/

import * as React from 'react';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @noflow
*/

import {
Expand Down
2 changes: 1 addition & 1 deletion packages/react-server/src/ReactFizzServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1668,7 +1668,7 @@ function erroredTask(
}
}

function abortTaskSoft(task: Task): void {
function abortTaskSoft(this: Request, task: Task): void {
// This aborts task without aborting the parent boundary that it blocks.
// It's used for when we didn't need this task to complete the tree.
// If task was needed, then it should use abortTask instead.
Expand Down
2 changes: 2 additions & 0 deletions packages/react/src/ReactForwardRef.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @noflow
*/

import {REACT_FORWARD_REF_TYPE, REACT_MEMO_TYPE} from 'shared/ReactSymbols';
Expand Down
2 changes: 2 additions & 0 deletions packages/react/src/ReactMemo.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @noflow
*/

import {REACT_MEMO_TYPE} from 'shared/ReactSymbols';
Expand Down
2 changes: 2 additions & 0 deletions packages/shared/forks/invokeGuardedCallbackImpl.www.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @noflow
*/

// Provided by www
Expand Down
31 changes: 31 additions & 0 deletions scripts/babel/getComments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

function getComments(path) {
const allComments = path.hub.file.ast.comments;
if (path.node.leadingComments) {
// Babel AST includes comments.
return path.node.leadingComments;
}
// In Hermes AST we need to find the comments by range.
const comments = [];
let line = path.node.loc.start.line;
let i = allComments.length - 1;
while (i >= 0 && allComments[i].loc.end.line >= line) {
i--;
}
while (i >= 0 && allComments[i].loc.end.line === line - 1) {
line = allComments[i].loc.start.line;
comments.unshift(allComments[i]);
i--;
}
return comments;
}

module.exports = getComments;
6 changes: 4 additions & 2 deletions scripts/babel/transform-react-version-pragma.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

/* eslint-disable no-for-of-loops/no-for-of-loops */

const getComments = require('./getComments');

const GATE_VERSION_STR = '@reactVersion ';

function transform(babel) {
Expand Down Expand Up @@ -65,7 +67,7 @@ function transform(babel) {
callee.name === 'it' ||
callee.name === 'fit'
) {
const comments = statement.leadingComments;
const comments = getComments(path);
const condition = buildGateVersionCondition(comments);
if (condition !== null) {
callee.name =
Expand All @@ -87,7 +89,7 @@ function transform(babel) {
callee.property.type === 'Identifier' &&
callee.property.name === 'only'
) {
const comments = statement.leadingComments;
const comments = getComments(path);
const condition = buildGateVersionCondition(comments);
if (condition !== null) {
statement.expression = t.callExpression(
Expand Down
6 changes: 4 additions & 2 deletions scripts/babel/transform-test-gate-pragma.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

/* eslint-disable no-for-of-loops/no-for-of-loops */

const getComments = require('./getComments');

function transform(babel) {
const {types: t} = babel;

Expand Down Expand Up @@ -278,7 +280,7 @@ function transform(babel) {
callee.name === 'it' ||
callee.name === 'fit'
) {
const comments = statement.leadingComments;
const comments = getComments(path);
if (comments !== undefined) {
const condition = buildGateCondition(comments);
if (condition !== null) {
Expand All @@ -304,7 +306,7 @@ function transform(babel) {
callee.property.type === 'Identifier' &&
callee.property.name === 'only'
) {
const comments = statement.leadingComments;
const comments = getComments(path);
if (comments !== undefined) {
const condition = buildGateCondition(comments);
if (condition !== null) {
Expand Down
5 changes: 4 additions & 1 deletion scripts/jest/preprocessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const path = require('path');

const babel = require('@babel/core');
const coffee = require('coffee-script');
const hermesParser = require('hermes-parser');

const tsPreprocessor = require('./typescript/preprocessor');
const createCacheKeyFunction = require('fbjs-scripts/jest/createCacheKeyFunction');
Expand Down Expand Up @@ -93,7 +94,9 @@ module.exports = {
) {
plugins.push(pathToTransformReactVersionPragma);
}
return babel.transform(
let sourceAst = hermesParser.parse(src, {babel: true});
return babel.transformFromAstSync(
sourceAst,
src,
Object.assign(
{filename: path.relative(process.cwd(), filePath)},
Expand Down
12 changes: 11 additions & 1 deletion scripts/rollup/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const rollup = require('rollup');
const babel = require('rollup-plugin-babel');
const closure = require('./plugins/closure-plugin');
const commonjs = require('rollup-plugin-commonjs');
const flowRemoveTypes = require('flow-remove-types');
const prettier = require('rollup-plugin-prettier');
const replace = require('rollup-plugin-replace');
const stripBanner = require('rollup-plugin-strip-banner');
Expand Down Expand Up @@ -99,7 +100,6 @@ const syncWWWPath = argv['sync-www'];
// Non-ES2015 stuff applied before closure compiler.
const babelPlugins = [
// These plugins filter out non-ES2015.
'@babel/plugin-transform-flow-strip-types',
['@babel/plugin-proposal-class-properties', {loose: true}],
'syntax-trailing-function-commas',
// These use loose mode which avoids embedding a runtime.
Expand Down Expand Up @@ -325,6 +325,16 @@ function getPlugins(
bundleType === RN_FB_PROFILING;
const shouldStayReadable = isFBWWWBundle || isRNBundle || forcePrettyOutput;
return [
{
name: 'rollup-plugin-flow-remove-types',
transform(code) {
const transformed = flowRemoveTypes(code);
return {
code: transformed.toString(),
map: transformed.generateMap(),
};
},
},
// Shim any modules that need forking in this environment.
useForks(forks),
// Ensure we don't try to bundle any fbjs modules.
Expand Down
23 changes: 22 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7920,6 +7920,20 @@ flow-bin@^0.190.0:
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.190.0.tgz#cfc50e1474facf8150232a6c498fe66a6bb75969"
integrity sha512-Qo3bvN3cmGFXsq63ZxcHFZXQDvgx84fCuq8cXuKk5xbvuebBGwMqS+ku/rH+gEkciRrcTYrXqoSzb9b6ShcoJg==

flow-parser@^0.196.1:
version "0.196.1"
resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.196.1.tgz#3c31f102454518f0c68eeb99f57501c2a0c9bff0"
integrity sha512-V3yaKHyBWhl+LF6sxgbfqxMlwoFKs8UKh2DYTrGj1AHi9ST7Zyp+9ToF4l9eoL6l/DxdFwCNF3MAJ1vCVrgJmw==

flow-remove-types@^2.196.1:
version "2.196.1"
resolved "https://registry.yarnpkg.com/flow-remove-types/-/flow-remove-types-2.196.1.tgz#c77ab53679beb1b1ba420c16865cea714a67defc"
integrity sha512-pAEe2B/fKtV96MVGWQgmjP5Z1nLeFFe++r83ql1Zj86+p+3IujsbvwxiXCiF/SS6ObbB6TmciCxxd+FsOUyY3Q==
dependencies:
flow-parser "^0.196.1"
pirates "^3.0.2"
vlq "^0.2.1"

fluent-syntax@0.13.0:
version "0.13.0"
resolved "https://registry.yarnpkg.com/fluent-syntax/-/fluent-syntax-0.13.0.tgz#417144d99cba94ff474c422b3e6623d5a842855a"
Expand Down Expand Up @@ -8749,7 +8763,7 @@ hermes-estree@0.9.0:
resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.9.0.tgz#026e0abe6db1dcf50a81a79014b779a83db3b814"
integrity sha512-5DZ7Y0CbHVk8zPqgRCvqp8iw+P05svnQDI1aJFjdqCfXJ/1CZ+8aYpGlhJ29zCG5SE5duGTzSxogAYYI4QqXqw==

hermes-parser@0.9.0:
hermes-parser@0.9.0, hermes-parser@^0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.9.0.tgz#ede3044d50479c61843cef5bbdcea83933d4e4ec"
integrity sha512-IcvJIlAn+9tpHkP+HTsxWKrIdQPp0gvGrrQmxlL4XnNS+Oh6R/Fpxbcoflm2kY3zgQjEvxZxLiK/2+k3/5wsrw==
Expand Down Expand Up @@ -12991,6 +13005,13 @@ pinpoint@^1.1.0:
resolved "https://registry.yarnpkg.com/pinpoint/-/pinpoint-1.1.0.tgz#0cf7757a6977f1bf7f6a32207b709e377388e874"
integrity sha1-DPd1eml38b9/ajIge3CeN3OI6HQ=

pirates@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/pirates/-/pirates-3.0.2.tgz#7e6f85413fd9161ab4e12b539b06010d85954bb9"
integrity sha512-c5CgUJq6H2k6MJz72Ak1F5sN9n9wlSlJyEnwvpm9/y3WB4E3pHBDT2c6PEiS1vyJvq2bUxUAIu0EGf8Cx4Ic7Q==
dependencies:
node-modules-regexp "^1.0.0"

pirates@^4.0.0, pirates@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87"
Expand Down

0 comments on commit b83baf6

Please sign in to comment.