-
-
Notifications
You must be signed in to change notification settings - Fork 298
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
Added support for resolving exported components within HOCs #124
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* Copyright (c) 2015, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
*/ | ||
|
||
/*global jest, describe, beforeEach, it, expect*/ | ||
|
||
jest.disableAutomock(); | ||
|
||
describe('resolveHOC', () => { | ||
var builders; | ||
var utils; | ||
var resolveHOC; | ||
|
||
function parse(src) { | ||
var root = utils.parse(src); | ||
return root.get('body', root.node.body.length - 1, 'expression'); | ||
} | ||
|
||
beforeEach(() => { | ||
var recast = require('recast'); | ||
builders = recast.types.builders; | ||
resolveHOC = require('../resolveHOC').default; | ||
utils = require('../../../tests/utils'); | ||
}); | ||
|
||
it('resolves simple hoc', () => { | ||
var path = parse([ | ||
'hoc(42);', | ||
].join('\n')); | ||
expect(resolveHOC(path).node).toEqualASTNode(builders.literal(42)); | ||
}); | ||
|
||
it('resolves simple hoc w/ multiple args', () => { | ||
var path = parse([ | ||
'hoc1(arg1a, arg1b)(42);', | ||
].join('\n')); | ||
expect(resolveHOC(path).node).toEqualASTNode(builders.literal(42)); | ||
}); | ||
|
||
it('resolves nested hocs', () => { | ||
var path = parse([ | ||
'hoc2(arg2b, arg2b)(', | ||
' hoc1(arg1a, arg2a)(42)', | ||
');', | ||
].join('\n')); | ||
expect(resolveHOC(path).node).toEqualASTNode(builders.literal(42)); | ||
}); | ||
|
||
it('resolves really nested hocs', () => { | ||
var path = parse([ | ||
'hoc3(arg3a, arg3b)(', | ||
' hoc2(arg2b, arg2b)(', | ||
' hoc1(arg1a, arg2a)(42)', | ||
' )', | ||
');', | ||
].join('\n')); | ||
expect(resolveHOC(path).node).toEqualASTNode(builders.literal(42)); | ||
}); | ||
|
||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* Copyright (c) 2015, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
* @flow | ||
* | ||
*/ | ||
|
||
import recast from 'recast'; | ||
import isReactCreateClassCall from './isReactCreateClassCall'; | ||
|
||
var { | ||
types: { | ||
NodePath, | ||
namedTypes: types, | ||
}, | ||
} = recast; | ||
|
||
/** | ||
* If the path is a call expression, it recursively resolves to the | ||
* rightmost argument, stopping if it finds a React.createClass call expression | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inspecting only the rightmost argument may not work for all cases. Also it might be interesting to investigate There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's interesting that Relay doesn't follow the convention I've seen for every other HOC, which is to take only one argument (the component) or have the component be the rightmost argument. Recompose follows this convention. But as discussed in #80 you can easily turn any HOC into a HOC that takes a component as its only or rightmost argument. |
||
* | ||
* Else the path itself is returned. | ||
*/ | ||
export default function resolveHOC(path: NodePath): NodePath { | ||
var node = path.node; | ||
if (types.CallExpression.check(node) && !isReactCreateClassCall(path)) { | ||
if (node.arguments.length) { | ||
return resolveHOC(path.get('arguments', node.arguments.length - 1)); | ||
} | ||
} | ||
|
||
return path; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about
isReactComponentClass
andisStatelessComponent
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
React Classes and stateless functional components are not call expressions, but
React.createClass()
is.