You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
1.9 KiB
75 lines
1.9 KiB
/** |
|
* @fileoverview Require component props to be typed as read-only. |
|
* @author Luke Zapart |
|
*/ |
|
|
|
'use strict'; |
|
|
|
const Components = require('../util/Components'); |
|
const docsUrl = require('../util/docsUrl'); |
|
|
|
function isFlowPropertyType(node) { |
|
return node.type === 'ObjectTypeProperty'; |
|
} |
|
|
|
function isCovariant(node) { |
|
return node.variance && node.variance.kind === 'plus'; |
|
} |
|
|
|
// ------------------------------------------------------------------------------ |
|
// Rule Definition |
|
// ------------------------------------------------------------------------------ |
|
|
|
module.exports = { |
|
meta: { |
|
docs: { |
|
description: 'Require read-only props.', |
|
category: 'Stylistic Issues', |
|
recommended: false, |
|
url: docsUrl('prefer-read-only-props') |
|
}, |
|
fixable: 'code', |
|
schema: [] |
|
}, |
|
|
|
create: Components.detect((context, components) => ({ |
|
'Program:exit': function () { |
|
const list = components.list(); |
|
|
|
Object.keys(list).forEach((key) => { |
|
const component = list[key]; |
|
|
|
if (!component.declaredPropTypes) { |
|
return; |
|
} |
|
|
|
Object.keys(component.declaredPropTypes).forEach((propName) => { |
|
const prop = component.declaredPropTypes[propName]; |
|
|
|
if (!isFlowPropertyType(prop.node)) { |
|
return; |
|
} |
|
|
|
if (!isCovariant(prop.node)) { |
|
context.report({ |
|
node: prop.node, |
|
message: 'Prop \'{{propName}}\' should be read-only.', |
|
data: { |
|
propName |
|
}, |
|
fix: (fixer) => { |
|
if (!prop.node.variance) { |
|
// Insert covariance |
|
return fixer.insertTextBefore(prop.node, '+'); |
|
} |
|
|
|
// Replace contravariance with covariance |
|
return fixer.replaceText(prop.node.variance, '+'); |
|
} |
|
}); |
|
} |
|
}); |
|
}); |
|
} |
|
})) |
|
};
|
|
|