Skip to content

Commit

Permalink
Merge branch 'lukeapage-misc/420'
Browse files Browse the repository at this point in the history
  • Loading branch information
gajus committed Jul 28, 2019
2 parents b0477b2 + 33917b6 commit e984856
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 23 deletions.
29 changes: 22 additions & 7 deletions src/rules/requireReadonlyReactProps.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ const isReactComponent = (node) => {

const create = (context) => {
const readOnlyTypes = [];
const foundTypes = [];
const reportedFunctionalComponents = [];

const isReadOnlyClassProp = (node) => {
const id = node.superTypeParameters.params[0].id;

return id && !reReadOnly.test(id.name) && !readOnlyTypes.includes(id.name);
return id && !reReadOnly.test(id.name) && !readOnlyTypes.includes(id.name) && foundTypes.includes(id.name);
};

const isReadOnlyObjectType = (node) => {
Expand All @@ -49,18 +50,31 @@ const create = (context) => {
};

const isReadOnlyType = (node) => {
return node.type === 'TypeAlias' && node.right.id && reReadOnly.test(node.right.id.name) || isReadOnlyObjectType(node.right);
return node.right.id && reReadOnly.test(node.right.id.name) || isReadOnlyObjectType(node.right);
};

for (const node of context.getSourceCode().ast.body) {
let idName;
let typeNode;

// type Props = $ReadOnly<{}>
if (isReadOnlyType(node) ||
if (node.type === 'TypeAlias') {
idName = node.id.name;
typeNode = node;

// export type Props = $ReadOnly<{}>
node.type === 'ExportNamedDeclaration' &&
// export type Props = $ReadOnly<{}>
} else if (node.type === 'ExportNamedDeclaration' &&
node.declaration &&
isReadOnlyType(node.declaration)) {
readOnlyTypes.push(node.id ? node.id.name : node.declaration.id.name);
node.declaration.type === 'TypeAlias') {
idName = node.declaration.id.name;
typeNode = node.declaration;
}

if (idName) {
foundTypes.push(idName);
if (isReadOnlyType(typeNode)) {
readOnlyTypes.push(idName);
}
}
}

Expand Down Expand Up @@ -101,6 +115,7 @@ const create = (context) => {
if (currentNode.params[0].type === 'Identifier' &&
(typeAnnotation = currentNode.params[0].typeAnnotation)) {
if ((identifier = typeAnnotation.typeAnnotation.id) &&
foundTypes.includes(identifier.name) &&
!readOnlyTypes.includes(identifier.name) &&
!reReadOnly.test(identifier.name)) {
if (reportedFunctionalComponents.includes(identifier)) {
Expand Down
22 changes: 6 additions & 16 deletions tests/rules/assertions/requireReadonlyReactProps.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,6 @@ export default {
}
]
},
{
code: 'class Foo extends React.Component<UnknownProps> { }',
errors: [
{
message: 'UnknownProps must be $ReadOnly'
}
]
},
{
code: 'export type Props = {}; class Foo extends Component<Props> { }',
errors: [
Expand Down Expand Up @@ -116,14 +108,6 @@ export default {
}
]
},
{
code: 'function Foo(props: UnknownProps) { return <p /> }',
errors: [
{
message: 'UnknownProps must be $ReadOnly'
}
]
},
{
code: 'export type Props = {}; function Foo(props: Props) { return <p /> }',
errors: [
Expand Down Expand Up @@ -184,6 +168,12 @@ export default {
{
code: 'class Foo extends Component<{||}> { }'
},
{
code: 'class Foo extends React.Component<UnknownProps> { }'
},
{
code: 'import { type Props } from "file"; class Foo extends React.Component<Props> { }'
},

// functional components
{
Expand Down

0 comments on commit e984856

Please sign in to comment.