main
js 83 lines 2.32 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @emails react-core
8 */
9
10 'use strict';
11
12 const fs = require('fs');
13 const path = require('path');
14 const errorMap = JSON.parse(
15 fs.readFileSync(path.resolve(__dirname, '../error-codes/codes.json'))
16 );
17 const errorMessages = new Set();
18 Object.keys(errorMap).forEach(key => errorMessages.add(errorMap[key]));
19
20 function nodeToErrorTemplate(node) {
21 if (node.type === 'Literal' && typeof node.value === 'string') {
22 return node.value;
23 } else if (node.type === 'BinaryExpression' && node.operator === '+') {
24 const l = nodeToErrorTemplate(node.left);
25 const r = nodeToErrorTemplate(node.right);
26 return l + r;
27 } else if (node.type === 'TemplateLiteral') {
28 let elements = [];
29 for (let i = 0; i < node.quasis.length; i++) {
30 const elementNode = node.quasis[i];
31 if (elementNode.type !== 'TemplateElement') {
32 throw new Error('Unsupported type ' + node.type);
33 }
34 elements.push(elementNode.value.cooked);
35 }
36 return elements.join('%s');
37 } else {
38 return '%s';
39 }
40 }
41
42 module.exports = {
43 meta: {
44 schema: [],
45 },
46 create(context) {
47 function ErrorCallExpression(node) {
48 const errorMessageNode = node.arguments[0];
49 if (errorMessageNode === undefined) {
50 return;
51 }
52 const errorMessage = nodeToErrorTemplate(errorMessageNode);
53 if (errorMessage === 'react-stack-top-frame') {
54 // This is a special case for generating stack traces.
55 return;
56 }
57 if (errorMessages.has(errorMessage)) {
58 return;
59 }
60 context.report({
61 node,
62 message:
63 'Error message does not have a corresponding production error code. Add ' +
64 'the following message to codes.json so it can be stripped ' +
65 'from the production builds:\n\n' +
66 errorMessage,
67 });
68 }
69
70 return {
71 NewExpression(node) {
72 if (node.callee.type === 'Identifier' && node.callee.name === 'Error') {
73 ErrorCallExpression(node);
74 }
75 },
76 CallExpression(node) {
77 if (node.callee.type === 'Identifier' && node.callee.name === 'Error') {
78 ErrorCallExpression(node);
79 }
80 },
81 };
82 },
83 };