Skip to content

Adding @extends React.Component support to isReactComponentClass #269

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 6, 2018
Merged

Adding @extends React.Component support to isReactComponentClass #269

merged 6 commits into from
Jun 6, 2018

Conversation

dusave
Copy link

@dusave dusave commented May 24, 2018

Certain react components may have multiple layers of inheritance and don't necessarily have a render function if it has a base class that handles rendering. In that case, react-docgen would fail to parse the file.

This PR:

  • Adds support for @extends React.Component in the class-level JSDoc block
  • Adds a unit test to verify functionality

Copy link

@decompil3d decompil3d left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good start. A few comments to tighten this up.

@@ -44,6 +44,26 @@ export default function isReactComponentClass(
return true;
}

// check for @extends React.Component in docblock
if (path.parentPath.value && path.parentPath.value) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the doubled-up check?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, should've been (path.parentPath&& path.parentPath.value)

classDeclaration = path.parentPath.value;
}

if (classDeclaration.leadingComments && classDeclaration.leadingComments.length > 0) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be more defensive and add a check for whether classDeclaration is truthy:

if (classDeclaration && classDeclaration.leadingComments && classDeclaration.leadingComments.length) {

(Note that checking the truthiness of length is sufficient rather than doing the explicit > 0)

}

if (classDeclaration.leadingComments && classDeclaration.leadingComments.length > 0) {
var matchedComments = classDeclaration.leadingComments.filter(function(comment) { return comment.value.match(/(@extends React.Component)/) });
Copy link

@decompil3d decompil3d May 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few issues:

  1. No need to wrap the inside of the RegExp with parentheses, since you're not using the capture for anything
  2. The . character in your RegExp will match anything -- you need to escape it to check for a literal period. Also, some people might indent the JSDoc field and value differently, so best to be lenient for that:
/@extends\s+React\.Component/
  1. No need to check through all of the comment lines -- you just need to find one that matches. So you can use Array.prototype.some to your advantage:
if (classDeclaration.leadingComments.some(function (comment) {
  return /@extends\s+React\.Component/.test(comment.value);
})) {
  return true;
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent points, getting all of that integrated.

}
if (classDeclaration &&
classDeclaration.leadingComments &&
classDeclaration.leadingComments.length &&

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for the length check, since some will handle an empty array just fine.

classDeclaration.leadingComments &&
classDeclaration.leadingComments.length &&
classDeclaration.leadingComments.some(function (comment) {
return /@extends\s+React\.Component/.test(comment.value);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indent this line.

if (path.parentPath && path.parentPath.value) {
var classDeclaration;
if (Array.isArray(path.parentPath.value)) {
var matches = path.parentPath.value.filter(function(declaration) { return declaration.type === 'ClassDeclaration' });
Copy link

@indexzero indexzero May 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could use .find here fwiw, which would let you make this a one liner

var classDeclaration = Array.isArray(path.parentPath.value)
  ? path.parentPath.value.find(function(declaration) { return declaration.type === 'ClassDeclaration' });
  : path.parentPath.value

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! So much cleaner.

classDeclaration = path.parentPath.value;
}

if (classDeclaration &&

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could tighten this up a bit more:

if (!classDeclaration || !classDeclaration.leadingComments) {
  return false;
}

return classDeclaration.leadingComments.some(function (comment) {
  return /@extends\s+React\.Component/.test(comment.value);
});

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we could do this.

if (!classDeclaration || !classDeclaration.leadingComments) {
  return false;
}

^ This would cause an early return. We still need to check to see if the component directly extends from React.Component.

@dusave
Copy link
Author

dusave commented Jun 5, 2018

Ping @danez @fkling. Would appreciate your help reviewing this feature so that we can resume using the mainline of react-docgen.

Copy link
Collaborator

@danez danez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, thank you

@danez danez merged commit 6a192c0 into reactjs:master Jun 6, 2018
danez pushed a commit that referenced this pull request Jun 6, 2018
)

* [component-verification] Adding additional method to verify component is a React Component

* [test] adding unit test

* [tiny] Initializing variable to satisfy TravisCI

* [fixes] incorporating feedback

* [fix] fixing a few more nits

* [refactor] cleaning up some checks
@indexzero indexzero deleted the extends-component branch June 8, 2018 20:55
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 28, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants