react-native/website/react-docgen/lib/resolver/findExportedReactCreateClas...

79 lines
2.2 KiB
JavaScript

/*
* 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
*/
"use strict";
var isExportsOrModuleAssignment =
require('../utils/isExportsOrModuleAssignment');
var isReactCreateClassCall = require('../utils/isReactCreateClassCall');
var resolveToValue = require('../utils/resolveToValue');
var ERROR_MULTIPLE_DEFINITIONS =
'Multiple exported component definitions found.';
function ignore() {
return false;
}
/**
* Given an AST, this function tries to find the object expression that is
* passed to `React.createClass`, by resolving all references properly.
*/
function findExportedReactCreateClass(
ast: ASTNode,
recast: Object
): ?NodePath {
var types = recast.types.namedTypes;
var definition;
recast.visit(ast, {
visitFunctionDeclaration: ignore,
visitFunctionExpression: ignore,
visitIfStatement: ignore,
visitWithStatement: ignore,
visitSwitchStatement: ignore,
visitCatchCause: ignore,
visitWhileStatement: ignore,
visitDoWhileStatement: ignore,
visitForStatement: ignore,
visitForInStatement: ignore,
visitAssignmentExpression: function(path) {
// Ignore anything that is not `exports.X = ...;` or
// `module.exports = ...;`
if (!isExportsOrModuleAssignment(path)) {
return false;
}
// Resolve the value of the right hand side. It should resolve to a call
// expression, something like React.createClass
path = resolveToValue(path.get('right'));
if (!isReactCreateClassCall(path)) {
return false;
}
if (definition) {
// If a file exports multiple components, ... complain!
throw new Error(ERROR_MULTIPLE_DEFINITIONS);
}
// We found React.createClass. Lets get cracking!
var resolvedPath = resolveToValue(path.get('arguments', 0));
if (types.ObjectExpression.check(resolvedPath.node)) {
definition = resolvedPath;
}
return false;
}
});
return definition;
}
module.exports = findExportedReactCreateClass;