source: imaps-frontend/node_modules/eslint-plugin-react/lib/rules/prefer-read-only-props.js@ d565449

main
Last change on this file since d565449 was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 3.0 KB
Line 
1/**
2 * @fileoverview Require component props to be typed as read-only.
3 * @author Luke Zapart
4 */
5
6'use strict';
7
8const flatMap = require('array.prototype.flatmap');
9const values = require('object.values');
10
11const Components = require('../util/Components');
12const docsUrl = require('../util/docsUrl');
13const report = require('../util/report');
14
15function isFlowPropertyType(node) {
16 return node.type === 'ObjectTypeProperty';
17}
18
19function isTypescriptPropertyType(node) {
20 return node.type === 'TSPropertySignature';
21}
22
23function isCovariant(node) {
24 return (node.variance && node.variance.kind === 'plus')
25 || (
26 node.parent
27 && node.parent.parent
28 && node.parent.parent.parent
29 && node.parent.parent.parent.id
30 && node.parent.parent.parent.id.name === '$ReadOnly'
31 );
32}
33
34function isReadonly(node) {
35 return (
36 node.typeAnnotation
37 && node.typeAnnotation.parent
38 && node.typeAnnotation.parent.readonly
39 );
40}
41
42// ------------------------------------------------------------------------------
43// Rule Definition
44// ------------------------------------------------------------------------------
45
46const messages = {
47 readOnlyProp: 'Prop \'{{name}}\' should be read-only.',
48};
49
50/** @type {import('eslint').Rule.RuleModule} */
51module.exports = {
52 meta: {
53 docs: {
54 description: 'Enforce that props are read-only',
55 category: 'Stylistic Issues',
56 recommended: false,
57 url: docsUrl('prefer-read-only-props'),
58 },
59 fixable: 'code',
60
61 messages,
62
63 schema: [],
64 },
65
66 create: Components.detect((context, components) => {
67 function reportReadOnlyProp(prop, propName, fixer) {
68 report(context, messages.readOnlyProp, 'readOnlyProp', {
69 node: prop.node,
70 data: {
71 name: propName,
72 },
73 fix: fixer,
74 });
75 }
76
77 return {
78 'Program:exit'() {
79 flatMap(
80 values(components.list()),
81 (component) => component.declaredPropTypes || []
82 ).forEach((declaredPropTypes) => {
83 Object.keys(declaredPropTypes).forEach((propName) => {
84 const prop = declaredPropTypes[propName];
85 if (!prop.node) {
86 return;
87 }
88
89 if (isFlowPropertyType(prop.node)) {
90 if (!isCovariant(prop.node)) {
91 reportReadOnlyProp(prop, propName, (fixer) => {
92 if (!prop.node.variance) {
93 // Insert covariance
94 return fixer.insertTextBefore(prop.node, '+');
95 }
96
97 // Replace contravariance with covariance
98 return fixer.replaceText(prop.node.variance, '+');
99 });
100 }
101
102 return;
103 }
104
105 if (isTypescriptPropertyType(prop.node)) {
106 if (!isReadonly(prop.node)) {
107 reportReadOnlyProp(prop, propName, (fixer) => (
108 fixer.insertTextBefore(prop.node, 'readonly ')
109 ));
110 }
111 }
112 });
113 });
114 },
115 };
116 }),
117};
Note: See TracBrowser for help on using the repository browser.