react-native-macos/packages/eslint-plugin-specs/react-native-modules.js

172 строки
4.1 KiB
JavaScript
Исходник Обычный вид История

/**
* 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.
*
* @emails react_native
* @format
*/
'use strict';
const path = require('path');
Use custom require hook to strip Flow types from NativeModule spec parser Summary: ## Context We currently run ESLint using `flow-node`. This is a very recent change that was introduced in these two diffs: - Switch VSCode ESLint plugin using flow-node: D24454702. - Switch all ESLint scripts to use flow-node: D24379783 (https://github.com/facebook/react-native/commit/ad5802cf916c1cbe3e142385a29810a0d7205c6c). ## Problem Because `react-native/eslint-plugin-codegen` (written in vanilla JavaScript) requires two files from `react-native-codegen` (written with Flow typings), we force all requires executed while initializing ESLint to compile out Flow types. Issues: - In the grand scheme of things, this is such a tiny and isolated problem. It shouldn't be the reason why we switch over to using flow node. That's a larger decision that should be discussed outside of this diff. - On VSCode cold start, in D24454702, I measured that using flow-node adds approximately 320ms to JavaScript file lint time. So, this is just slow. ## Solution - Switch ESLint back to using regular node: - Revert the changes to VSCode's ESLint plugin: D24454702 - Revert the changes to the internal ESLint scripts: D24379783 (https://github.com/facebook/react-native/commit/ad5802cf916c1cbe3e142385a29810a0d7205c6c). - Inside the ESLint plugin, register a temporary require hook to remove Flow types from the NativeModule spec parser, before we require it. We de-register this hook after the requires finish. ## Implementation Notes: - The `with-babel-register/` is a fork of `babel/register`, except I simplified the implementation based on the assumption that we're using it literally to only compile `react-native-codegen`. - `with-babel-register/` uses a disk cache, so we only call transformSync when a the input file (1) hasn't been transformed before, or (2) the cache entry was created before the file was last modified. - I ported over the source-map logic, so that when the NativeModule spec parser throws non-parsing errors, we get the correct stack trace. **Note:** I'm not sure if the source maps will work if there's a babel/register earlier during initialization. However, I don't think this will pose an actual problem, since we don't use a babel/register hook earlier. So, I think we should punt on this investigation. ## Alternative: Why aren't we using babel/register? Every time you call babel/register, it replaces the last registered hook. We don't want the ESLint plugin to be changing any existing require hooks that people have set up. Abandoned diff with babel/register: D24519349. Changelog: [Internal] Reviewed By: cpojer Differential Revision: D24551549 fbshipit-source-id: bbd7c5be44f74c0e9adbb20fe86e09802410b123
2020-10-27 10:38:54 +03:00
const withBabelRegister = require('./with-babel-register');
// We run yarn prepublish before publishing package which will set this value to true
const PACKAGE_USAGE = false;
Make RN Modules ESLint rule call into NativeModule spec parser Summary: This diff guts the React Native Modules ESLint rule, and makes it instead call into the NativeModule spec parser. After calling into the parser, the lint rule loops over all collected errors, and reports them. ## Benefits - There is now one source of truth of what is a "correct" NativeModule spec: The NativeModule spec parser. - Every change we make to the NativeModule spec parser will reflect in the lint rule. We have a number of changes planned for the NativeModule parser that will change what it means for a NativeModule spec to be correct. These changes now won't have to be duplicated in the ESLint rule. - The linter will *never* show any false positive errors. If there's an error in the linter, you *need* to fix it. Otherwise, the codegen *will* fail. This is huge. Previously, people were used to ignoring the linter, because it over-reported errors. This behavior won't slide after this stack lands. NOTE: This will run the NativeModules parser on all our NativeModule specs. We may have to check the specs, or the parser. Therefore, this could take some time to land. ## How does the lint rule work now? In every JavaScript file, the ESLint rule looks for `CallExpression` AST Nodes. Once it detects a `CallExpression` that corresponds to a `TurboModuleRegistry.get` or `TurboModuleRegistry.getEnforcing` it: 1. Marks the file as a TurboModule spec 2. Validates the `CallExpression` to verify that it is called with the <Spec> type parameters (i.e: like this: TurboModuleRegistry.get<Spec>(...)). When we're done the visition for the JavaScript file (i.e: in `Program:exit`), if the JavaScript file was a TurboModule spec: 1. Report a lint error if the filename doesn't start with Native. 2. We parse the source using flow-parser, and run the NativeModule spec parser on it. We capture all ParserErrors and report them via ESLint. ## When can I start using this lint rule in VSCode? I made the ESLint VSCode plugin use flow-node in D24454702. It'll take 3-4 weeks for this change to be shipped to everyone's VSCode. After the update, the linter will automatically start working in VSCode. Until then, we'll only get feedback on Sandcastle/Landcastle for lint rule violations. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D24379783 fbshipit-source-id: 222778d8a84d7010eb7b3ad71b34a7fe1f52e509
2020-10-24 13:42:17 +03:00
const ERRORS = {
misnamedHasteModule(hasteModuleName) {
return `Module ${hasteModuleName}: All files using TurboModuleRegistry must start with Native.`;
},
};
Use custom require hook to strip Flow types from NativeModule spec parser Summary: ## Context We currently run ESLint using `flow-node`. This is a very recent change that was introduced in these two diffs: - Switch VSCode ESLint plugin using flow-node: D24454702. - Switch all ESLint scripts to use flow-node: D24379783 (https://github.com/facebook/react-native/commit/ad5802cf916c1cbe3e142385a29810a0d7205c6c). ## Problem Because `react-native/eslint-plugin-codegen` (written in vanilla JavaScript) requires two files from `react-native-codegen` (written with Flow typings), we force all requires executed while initializing ESLint to compile out Flow types. Issues: - In the grand scheme of things, this is such a tiny and isolated problem. It shouldn't be the reason why we switch over to using flow node. That's a larger decision that should be discussed outside of this diff. - On VSCode cold start, in D24454702, I measured that using flow-node adds approximately 320ms to JavaScript file lint time. So, this is just slow. ## Solution - Switch ESLint back to using regular node: - Revert the changes to VSCode's ESLint plugin: D24454702 - Revert the changes to the internal ESLint scripts: D24379783 (https://github.com/facebook/react-native/commit/ad5802cf916c1cbe3e142385a29810a0d7205c6c). - Inside the ESLint plugin, register a temporary require hook to remove Flow types from the NativeModule spec parser, before we require it. We de-register this hook after the requires finish. ## Implementation Notes: - The `with-babel-register/` is a fork of `babel/register`, except I simplified the implementation based on the assumption that we're using it literally to only compile `react-native-codegen`. - `with-babel-register/` uses a disk cache, so we only call transformSync when a the input file (1) hasn't been transformed before, or (2) the cache entry was created before the file was last modified. - I ported over the source-map logic, so that when the NativeModule spec parser throws non-parsing errors, we get the correct stack trace. **Note:** I'm not sure if the source maps will work if there's a babel/register earlier during initialization. However, I don't think this will pose an actual problem, since we don't use a babel/register hook earlier. So, I think we should punt on this investigation. ## Alternative: Why aren't we using babel/register? Every time you call babel/register, it replaces the last registered hook. We don't want the ESLint plugin to be changing any existing require hooks that people have set up. Abandoned diff with babel/register: D24519349. Changelog: [Internal] Reviewed By: cpojer Differential Revision: D24551549 fbshipit-source-id: bbd7c5be44f74c0e9adbb20fe86e09802410b123
2020-10-27 10:38:54 +03:00
let RNModuleParser;
let RNParserUtils;
function requireModuleParser() {
if (RNModuleParser == null || RNParserUtils == null) {
// If using this externally, we leverage react-native-codegen as published form
if (!PACKAGE_USAGE) {
const config = {
only: [/react-native-codegen\/src\//],
plugins: [require('@babel/plugin-transform-flow-strip-types').default],
};
withBabelRegister(config, () => {
RNModuleParser = require('react-native-codegen/src/parsers/flow/modules');
RNParserUtils = require('react-native-codegen/src/parsers/flow/utils');
});
} else {
const config = {
only: [/react-native-codegen\/lib\//],
plugins: [require('@babel/plugin-transform-flow-strip-types').default],
};
withBabelRegister(config, () => {
RNModuleParser = require('react-native-codegen/lib/parsers/flow/modules');
RNParserUtils = require('react-native-codegen/lib/parsers/flow/utils');
});
}
Use custom require hook to strip Flow types from NativeModule spec parser Summary: ## Context We currently run ESLint using `flow-node`. This is a very recent change that was introduced in these two diffs: - Switch VSCode ESLint plugin using flow-node: D24454702. - Switch all ESLint scripts to use flow-node: D24379783 (https://github.com/facebook/react-native/commit/ad5802cf916c1cbe3e142385a29810a0d7205c6c). ## Problem Because `react-native/eslint-plugin-codegen` (written in vanilla JavaScript) requires two files from `react-native-codegen` (written with Flow typings), we force all requires executed while initializing ESLint to compile out Flow types. Issues: - In the grand scheme of things, this is such a tiny and isolated problem. It shouldn't be the reason why we switch over to using flow node. That's a larger decision that should be discussed outside of this diff. - On VSCode cold start, in D24454702, I measured that using flow-node adds approximately 320ms to JavaScript file lint time. So, this is just slow. ## Solution - Switch ESLint back to using regular node: - Revert the changes to VSCode's ESLint plugin: D24454702 - Revert the changes to the internal ESLint scripts: D24379783 (https://github.com/facebook/react-native/commit/ad5802cf916c1cbe3e142385a29810a0d7205c6c). - Inside the ESLint plugin, register a temporary require hook to remove Flow types from the NativeModule spec parser, before we require it. We de-register this hook after the requires finish. ## Implementation Notes: - The `with-babel-register/` is a fork of `babel/register`, except I simplified the implementation based on the assumption that we're using it literally to only compile `react-native-codegen`. - `with-babel-register/` uses a disk cache, so we only call transformSync when a the input file (1) hasn't been transformed before, or (2) the cache entry was created before the file was last modified. - I ported over the source-map logic, so that when the NativeModule spec parser throws non-parsing errors, we get the correct stack trace. **Note:** I'm not sure if the source maps will work if there's a babel/register earlier during initialization. However, I don't think this will pose an actual problem, since we don't use a babel/register hook earlier. So, I think we should punt on this investigation. ## Alternative: Why aren't we using babel/register? Every time you call babel/register, it replaces the last registered hook. We don't want the ESLint plugin to be changing any existing require hooks that people have set up. Abandoned diff with babel/register: D24519349. Changelog: [Internal] Reviewed By: cpojer Differential Revision: D24551549 fbshipit-source-id: bbd7c5be44f74c0e9adbb20fe86e09802410b123
2020-10-27 10:38:54 +03:00
}
return {
buildModuleSchema: RNModuleParser.buildModuleSchema,
createParserErrorCapturer: RNParserUtils.createParserErrorCapturer,
};
}
const VALID_SPEC_NAMES = /^Native\S+$/;
function isModuleRequire(node) {
if (node.type !== 'CallExpression') {
return false;
}
const callExpression = node;
if (callExpression.callee.type !== 'MemberExpression') {
return false;
}
const memberExpression = callExpression.callee;
if (
!(
memberExpression.object.type === 'Identifier' &&
memberExpression.object.name === 'TurboModuleRegistry'
)
) {
return false;
}
if (
!(
memberExpression.property.type === 'Identifier' &&
(memberExpression.property.name === 'get' ||
memberExpression.property.name === 'getEnforcing')
)
) {
return false;
}
return true;
}
function isGeneratedFile(context) {
return (
context
.getSourceCode()
.getText()
.indexOf('@' + 'generated SignedSource<<') !== -1
);
}
/**
* A lint rule to guide best practices in writing type safe React NativeModules.
*/
function rule(context) {
const filename = context.getFilename();
Make RN Modules ESLint rule call into NativeModule spec parser Summary: This diff guts the React Native Modules ESLint rule, and makes it instead call into the NativeModule spec parser. After calling into the parser, the lint rule loops over all collected errors, and reports them. ## Benefits - There is now one source of truth of what is a "correct" NativeModule spec: The NativeModule spec parser. - Every change we make to the NativeModule spec parser will reflect in the lint rule. We have a number of changes planned for the NativeModule parser that will change what it means for a NativeModule spec to be correct. These changes now won't have to be duplicated in the ESLint rule. - The linter will *never* show any false positive errors. If there's an error in the linter, you *need* to fix it. Otherwise, the codegen *will* fail. This is huge. Previously, people were used to ignoring the linter, because it over-reported errors. This behavior won't slide after this stack lands. NOTE: This will run the NativeModules parser on all our NativeModule specs. We may have to check the specs, or the parser. Therefore, this could take some time to land. ## How does the lint rule work now? In every JavaScript file, the ESLint rule looks for `CallExpression` AST Nodes. Once it detects a `CallExpression` that corresponds to a `TurboModuleRegistry.get` or `TurboModuleRegistry.getEnforcing` it: 1. Marks the file as a TurboModule spec 2. Validates the `CallExpression` to verify that it is called with the <Spec> type parameters (i.e: like this: TurboModuleRegistry.get<Spec>(...)). When we're done the visition for the JavaScript file (i.e: in `Program:exit`), if the JavaScript file was a TurboModule spec: 1. Report a lint error if the filename doesn't start with Native. 2. We parse the source using flow-parser, and run the NativeModule spec parser on it. We capture all ParserErrors and report them via ESLint. ## When can I start using this lint rule in VSCode? I made the ESLint VSCode plugin use flow-node in D24454702. It'll take 3-4 weeks for this change to be shipped to everyone's VSCode. After the update, the linter will automatically start working in VSCode. Until then, we'll only get feedback on Sandcastle/Landcastle for lint rule violations. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D24379783 fbshipit-source-id: 222778d8a84d7010eb7b3ad71b34a7fe1f52e509
2020-10-24 13:42:17 +03:00
const hasteModuleName = path.basename(filename).replace(/\.js$/, '');
if (isGeneratedFile(context)) {
return {};
}
let isModule = false;
return {
'Program:exit': function (node) {
if (!isModule) {
Make RN Modules ESLint rule call into NativeModule spec parser Summary: This diff guts the React Native Modules ESLint rule, and makes it instead call into the NativeModule spec parser. After calling into the parser, the lint rule loops over all collected errors, and reports them. ## Benefits - There is now one source of truth of what is a "correct" NativeModule spec: The NativeModule spec parser. - Every change we make to the NativeModule spec parser will reflect in the lint rule. We have a number of changes planned for the NativeModule parser that will change what it means for a NativeModule spec to be correct. These changes now won't have to be duplicated in the ESLint rule. - The linter will *never* show any false positive errors. If there's an error in the linter, you *need* to fix it. Otherwise, the codegen *will* fail. This is huge. Previously, people were used to ignoring the linter, because it over-reported errors. This behavior won't slide after this stack lands. NOTE: This will run the NativeModules parser on all our NativeModule specs. We may have to check the specs, or the parser. Therefore, this could take some time to land. ## How does the lint rule work now? In every JavaScript file, the ESLint rule looks for `CallExpression` AST Nodes. Once it detects a `CallExpression` that corresponds to a `TurboModuleRegistry.get` or `TurboModuleRegistry.getEnforcing` it: 1. Marks the file as a TurboModule spec 2. Validates the `CallExpression` to verify that it is called with the <Spec> type parameters (i.e: like this: TurboModuleRegistry.get<Spec>(...)). When we're done the visition for the JavaScript file (i.e: in `Program:exit`), if the JavaScript file was a TurboModule spec: 1. Report a lint error if the filename doesn't start with Native. 2. We parse the source using flow-parser, and run the NativeModule spec parser on it. We capture all ParserErrors and report them via ESLint. ## When can I start using this lint rule in VSCode? I made the ESLint VSCode plugin use flow-node in D24454702. It'll take 3-4 weeks for this change to be shipped to everyone's VSCode. After the update, the linter will automatically start working in VSCode. Until then, we'll only get feedback on Sandcastle/Landcastle for lint rule violations. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D24379783 fbshipit-source-id: 222778d8a84d7010eb7b3ad71b34a7fe1f52e509
2020-10-24 13:42:17 +03:00
return;
}
// Report invalid file names
if (!VALID_SPEC_NAMES.test(hasteModuleName)) {
context.report({
node,
message: ERRORS.misnamedHasteModule(hasteModuleName),
});
}
Make RN Modules ESLint rule call into NativeModule spec parser Summary: This diff guts the React Native Modules ESLint rule, and makes it instead call into the NativeModule spec parser. After calling into the parser, the lint rule loops over all collected errors, and reports them. ## Benefits - There is now one source of truth of what is a "correct" NativeModule spec: The NativeModule spec parser. - Every change we make to the NativeModule spec parser will reflect in the lint rule. We have a number of changes planned for the NativeModule parser that will change what it means for a NativeModule spec to be correct. These changes now won't have to be duplicated in the ESLint rule. - The linter will *never* show any false positive errors. If there's an error in the linter, you *need* to fix it. Otherwise, the codegen *will* fail. This is huge. Previously, people were used to ignoring the linter, because it over-reported errors. This behavior won't slide after this stack lands. NOTE: This will run the NativeModules parser on all our NativeModule specs. We may have to check the specs, or the parser. Therefore, this could take some time to land. ## How does the lint rule work now? In every JavaScript file, the ESLint rule looks for `CallExpression` AST Nodes. Once it detects a `CallExpression` that corresponds to a `TurboModuleRegistry.get` or `TurboModuleRegistry.getEnforcing` it: 1. Marks the file as a TurboModule spec 2. Validates the `CallExpression` to verify that it is called with the <Spec> type parameters (i.e: like this: TurboModuleRegistry.get<Spec>(...)). When we're done the visition for the JavaScript file (i.e: in `Program:exit`), if the JavaScript file was a TurboModule spec: 1. Report a lint error if the filename doesn't start with Native. 2. We parse the source using flow-parser, and run the NativeModule spec parser on it. We capture all ParserErrors and report them via ESLint. ## When can I start using this lint rule in VSCode? I made the ESLint VSCode plugin use flow-node in D24454702. It'll take 3-4 weeks for this change to be shipped to everyone's VSCode. After the update, the linter will automatically start working in VSCode. Until then, we'll only get feedback on Sandcastle/Landcastle for lint rule violations. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D24379783 fbshipit-source-id: 222778d8a84d7010eb7b3ad71b34a7fe1f52e509
2020-10-24 13:42:17 +03:00
const {buildModuleSchema, createParserErrorCapturer} =
requireModuleParser();
Make RN Modules ESLint rule call into NativeModule spec parser Summary: This diff guts the React Native Modules ESLint rule, and makes it instead call into the NativeModule spec parser. After calling into the parser, the lint rule loops over all collected errors, and reports them. ## Benefits - There is now one source of truth of what is a "correct" NativeModule spec: The NativeModule spec parser. - Every change we make to the NativeModule spec parser will reflect in the lint rule. We have a number of changes planned for the NativeModule parser that will change what it means for a NativeModule spec to be correct. These changes now won't have to be duplicated in the ESLint rule. - The linter will *never* show any false positive errors. If there's an error in the linter, you *need* to fix it. Otherwise, the codegen *will* fail. This is huge. Previously, people were used to ignoring the linter, because it over-reported errors. This behavior won't slide after this stack lands. NOTE: This will run the NativeModules parser on all our NativeModule specs. We may have to check the specs, or the parser. Therefore, this could take some time to land. ## How does the lint rule work now? In every JavaScript file, the ESLint rule looks for `CallExpression` AST Nodes. Once it detects a `CallExpression` that corresponds to a `TurboModuleRegistry.get` or `TurboModuleRegistry.getEnforcing` it: 1. Marks the file as a TurboModule spec 2. Validates the `CallExpression` to verify that it is called with the <Spec> type parameters (i.e: like this: TurboModuleRegistry.get<Spec>(...)). When we're done the visition for the JavaScript file (i.e: in `Program:exit`), if the JavaScript file was a TurboModule spec: 1. Report a lint error if the filename doesn't start with Native. 2. We parse the source using flow-parser, and run the NativeModule spec parser on it. We capture all ParserErrors and report them via ESLint. ## When can I start using this lint rule in VSCode? I made the ESLint VSCode plugin use flow-node in D24454702. It'll take 3-4 weeks for this change to be shipped to everyone's VSCode. After the update, the linter will automatically start working in VSCode. Until then, we'll only get feedback on Sandcastle/Landcastle for lint rule violations. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D24379783 fbshipit-source-id: 222778d8a84d7010eb7b3ad71b34a7fe1f52e509
2020-10-24 13:42:17 +03:00
const flowParser = require('flow-parser');
Use custom require hook to strip Flow types from NativeModule spec parser Summary: ## Context We currently run ESLint using `flow-node`. This is a very recent change that was introduced in these two diffs: - Switch VSCode ESLint plugin using flow-node: D24454702. - Switch all ESLint scripts to use flow-node: D24379783 (https://github.com/facebook/react-native/commit/ad5802cf916c1cbe3e142385a29810a0d7205c6c). ## Problem Because `react-native/eslint-plugin-codegen` (written in vanilla JavaScript) requires two files from `react-native-codegen` (written with Flow typings), we force all requires executed while initializing ESLint to compile out Flow types. Issues: - In the grand scheme of things, this is such a tiny and isolated problem. It shouldn't be the reason why we switch over to using flow node. That's a larger decision that should be discussed outside of this diff. - On VSCode cold start, in D24454702, I measured that using flow-node adds approximately 320ms to JavaScript file lint time. So, this is just slow. ## Solution - Switch ESLint back to using regular node: - Revert the changes to VSCode's ESLint plugin: D24454702 - Revert the changes to the internal ESLint scripts: D24379783 (https://github.com/facebook/react-native/commit/ad5802cf916c1cbe3e142385a29810a0d7205c6c). - Inside the ESLint plugin, register a temporary require hook to remove Flow types from the NativeModule spec parser, before we require it. We de-register this hook after the requires finish. ## Implementation Notes: - The `with-babel-register/` is a fork of `babel/register`, except I simplified the implementation based on the assumption that we're using it literally to only compile `react-native-codegen`. - `with-babel-register/` uses a disk cache, so we only call transformSync when a the input file (1) hasn't been transformed before, or (2) the cache entry was created before the file was last modified. - I ported over the source-map logic, so that when the NativeModule spec parser throws non-parsing errors, we get the correct stack trace. **Note:** I'm not sure if the source maps will work if there's a babel/register earlier during initialization. However, I don't think this will pose an actual problem, since we don't use a babel/register hook earlier. So, I think we should punt on this investigation. ## Alternative: Why aren't we using babel/register? Every time you call babel/register, it replaces the last registered hook. We don't want the ESLint plugin to be changing any existing require hooks that people have set up. Abandoned diff with babel/register: D24519349. Changelog: [Internal] Reviewed By: cpojer Differential Revision: D24551549 fbshipit-source-id: bbd7c5be44f74c0e9adbb20fe86e09802410b123
2020-10-27 10:38:54 +03:00
const [parsingErrors, tryParse] = createParserErrorCapturer();
Make RN Modules ESLint rule call into NativeModule spec parser Summary: This diff guts the React Native Modules ESLint rule, and makes it instead call into the NativeModule spec parser. After calling into the parser, the lint rule loops over all collected errors, and reports them. ## Benefits - There is now one source of truth of what is a "correct" NativeModule spec: The NativeModule spec parser. - Every change we make to the NativeModule spec parser will reflect in the lint rule. We have a number of changes planned for the NativeModule parser that will change what it means for a NativeModule spec to be correct. These changes now won't have to be duplicated in the ESLint rule. - The linter will *never* show any false positive errors. If there's an error in the linter, you *need* to fix it. Otherwise, the codegen *will* fail. This is huge. Previously, people were used to ignoring the linter, because it over-reported errors. This behavior won't slide after this stack lands. NOTE: This will run the NativeModules parser on all our NativeModule specs. We may have to check the specs, or the parser. Therefore, this could take some time to land. ## How does the lint rule work now? In every JavaScript file, the ESLint rule looks for `CallExpression` AST Nodes. Once it detects a `CallExpression` that corresponds to a `TurboModuleRegistry.get` or `TurboModuleRegistry.getEnforcing` it: 1. Marks the file as a TurboModule spec 2. Validates the `CallExpression` to verify that it is called with the <Spec> type parameters (i.e: like this: TurboModuleRegistry.get<Spec>(...)). When we're done the visition for the JavaScript file (i.e: in `Program:exit`), if the JavaScript file was a TurboModule spec: 1. Report a lint error if the filename doesn't start with Native. 2. We parse the source using flow-parser, and run the NativeModule spec parser on it. We capture all ParserErrors and report them via ESLint. ## When can I start using this lint rule in VSCode? I made the ESLint VSCode plugin use flow-node in D24454702. It'll take 3-4 weeks for this change to be shipped to everyone's VSCode. After the update, the linter will automatically start working in VSCode. Until then, we'll only get feedback on Sandcastle/Landcastle for lint rule violations. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D24379783 fbshipit-source-id: 222778d8a84d7010eb7b3ad71b34a7fe1f52e509
2020-10-24 13:42:17 +03:00
const sourceCode = context.getSourceCode().getText();
const ast = flowParser.parse(sourceCode);
tryParse(() => {
buildModuleSchema(hasteModuleName, ast, tryParse);
});
Make RN Modules ESLint rule call into NativeModule spec parser Summary: This diff guts the React Native Modules ESLint rule, and makes it instead call into the NativeModule spec parser. After calling into the parser, the lint rule loops over all collected errors, and reports them. ## Benefits - There is now one source of truth of what is a "correct" NativeModule spec: The NativeModule spec parser. - Every change we make to the NativeModule spec parser will reflect in the lint rule. We have a number of changes planned for the NativeModule parser that will change what it means for a NativeModule spec to be correct. These changes now won't have to be duplicated in the ESLint rule. - The linter will *never* show any false positive errors. If there's an error in the linter, you *need* to fix it. Otherwise, the codegen *will* fail. This is huge. Previously, people were used to ignoring the linter, because it over-reported errors. This behavior won't slide after this stack lands. NOTE: This will run the NativeModules parser on all our NativeModule specs. We may have to check the specs, or the parser. Therefore, this could take some time to land. ## How does the lint rule work now? In every JavaScript file, the ESLint rule looks for `CallExpression` AST Nodes. Once it detects a `CallExpression` that corresponds to a `TurboModuleRegistry.get` or `TurboModuleRegistry.getEnforcing` it: 1. Marks the file as a TurboModule spec 2. Validates the `CallExpression` to verify that it is called with the <Spec> type parameters (i.e: like this: TurboModuleRegistry.get<Spec>(...)). When we're done the visition for the JavaScript file (i.e: in `Program:exit`), if the JavaScript file was a TurboModule spec: 1. Report a lint error if the filename doesn't start with Native. 2. We parse the source using flow-parser, and run the NativeModule spec parser on it. We capture all ParserErrors and report them via ESLint. ## When can I start using this lint rule in VSCode? I made the ESLint VSCode plugin use flow-node in D24454702. It'll take 3-4 weeks for this change to be shipped to everyone's VSCode. After the update, the linter will automatically start working in VSCode. Until then, we'll only get feedback on Sandcastle/Landcastle for lint rule violations. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D24379783 fbshipit-source-id: 222778d8a84d7010eb7b3ad71b34a7fe1f52e509
2020-10-24 13:42:17 +03:00
parsingErrors.forEach(error => {
error.nodes.forEach(flowNode => {
context.report({
loc: flowNode.loc,
message: error.message,
});
Make RN Modules ESLint rule call into NativeModule spec parser Summary: This diff guts the React Native Modules ESLint rule, and makes it instead call into the NativeModule spec parser. After calling into the parser, the lint rule loops over all collected errors, and reports them. ## Benefits - There is now one source of truth of what is a "correct" NativeModule spec: The NativeModule spec parser. - Every change we make to the NativeModule spec parser will reflect in the lint rule. We have a number of changes planned for the NativeModule parser that will change what it means for a NativeModule spec to be correct. These changes now won't have to be duplicated in the ESLint rule. - The linter will *never* show any false positive errors. If there's an error in the linter, you *need* to fix it. Otherwise, the codegen *will* fail. This is huge. Previously, people were used to ignoring the linter, because it over-reported errors. This behavior won't slide after this stack lands. NOTE: This will run the NativeModules parser on all our NativeModule specs. We may have to check the specs, or the parser. Therefore, this could take some time to land. ## How does the lint rule work now? In every JavaScript file, the ESLint rule looks for `CallExpression` AST Nodes. Once it detects a `CallExpression` that corresponds to a `TurboModuleRegistry.get` or `TurboModuleRegistry.getEnforcing` it: 1. Marks the file as a TurboModule spec 2. Validates the `CallExpression` to verify that it is called with the <Spec> type parameters (i.e: like this: TurboModuleRegistry.get<Spec>(...)). When we're done the visition for the JavaScript file (i.e: in `Program:exit`), if the JavaScript file was a TurboModule spec: 1. Report a lint error if the filename doesn't start with Native. 2. We parse the source using flow-parser, and run the NativeModule spec parser on it. We capture all ParserErrors and report them via ESLint. ## When can I start using this lint rule in VSCode? I made the ESLint VSCode plugin use flow-node in D24454702. It'll take 3-4 weeks for this change to be shipped to everyone's VSCode. After the update, the linter will automatically start working in VSCode. Until then, we'll only get feedback on Sandcastle/Landcastle for lint rule violations. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D24379783 fbshipit-source-id: 222778d8a84d7010eb7b3ad71b34a7fe1f52e509
2020-10-24 13:42:17 +03:00
});
});
},
CallExpression(node) {
if (!isModuleRequire(node)) {
return;
}
isModule = true;
},
InterfaceExtends(node) {
if (node.id.name !== 'TurboModule') {
return;
}
isModule = true;
},
};
}
Make RN Modules ESLint rule call into NativeModule spec parser Summary: This diff guts the React Native Modules ESLint rule, and makes it instead call into the NativeModule spec parser. After calling into the parser, the lint rule loops over all collected errors, and reports them. ## Benefits - There is now one source of truth of what is a "correct" NativeModule spec: The NativeModule spec parser. - Every change we make to the NativeModule spec parser will reflect in the lint rule. We have a number of changes planned for the NativeModule parser that will change what it means for a NativeModule spec to be correct. These changes now won't have to be duplicated in the ESLint rule. - The linter will *never* show any false positive errors. If there's an error in the linter, you *need* to fix it. Otherwise, the codegen *will* fail. This is huge. Previously, people were used to ignoring the linter, because it over-reported errors. This behavior won't slide after this stack lands. NOTE: This will run the NativeModules parser on all our NativeModule specs. We may have to check the specs, or the parser. Therefore, this could take some time to land. ## How does the lint rule work now? In every JavaScript file, the ESLint rule looks for `CallExpression` AST Nodes. Once it detects a `CallExpression` that corresponds to a `TurboModuleRegistry.get` or `TurboModuleRegistry.getEnforcing` it: 1. Marks the file as a TurboModule spec 2. Validates the `CallExpression` to verify that it is called with the <Spec> type parameters (i.e: like this: TurboModuleRegistry.get<Spec>(...)). When we're done the visition for the JavaScript file (i.e: in `Program:exit`), if the JavaScript file was a TurboModule spec: 1. Report a lint error if the filename doesn't start with Native. 2. We parse the source using flow-parser, and run the NativeModule spec parser on it. We capture all ParserErrors and report them via ESLint. ## When can I start using this lint rule in VSCode? I made the ESLint VSCode plugin use flow-node in D24454702. It'll take 3-4 weeks for this change to be shipped to everyone's VSCode. After the update, the linter will automatically start working in VSCode. Until then, we'll only get feedback on Sandcastle/Landcastle for lint rule violations. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D24379783 fbshipit-source-id: 222778d8a84d7010eb7b3ad71b34a7fe1f52e509
2020-10-24 13:42:17 +03:00
rule.errors = ERRORS;
module.exports = rule;