Kevin Lacker 857bae4ea3 Replace the deprecated esprima-fb parser with flow-parser, on the RN website
Summary:
(I changed a ton from when I previously submitted this PR so please take another look if you already did.)

PROBLEM: the no-longer-maintained `esprima-fb` parser does not support class properties, leading our website docgen to die if we use class properties, which we're gonna do real soon now
SOLUTION: use `flow-parser` instead, which the flow team is maintaining including all the fancy-pants ES? stuff that FB uses internally.

This removes the `esprima-fb` parser from jsdocs and replaces it with `flow-parser`. It's almost the same, I checked by diffing all the parser json output and it only had a few irrelevant differences. I had to add a file of constants so that we could remove esprima-fb altogether, too.

This also adds a couple unit tests, so that we can test that jsDocs works programmatically. They don't run if you run the regular RN tests, you have to run `npm test` from the `/website/` subdirectory.
Closes https://github.com/facebook/react-native/pull/9890

Differential Revision: D3865629

Pulled By: bestander

fbshipit-source-id: 8f561b78ca4a02f3f7b45e55904ec2fa911e3bb6
2016-09-14 14:28:44 -07:00

87 lines
2.4 KiB
JavaScript

/**
* Copyright (c) 2015-present, 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 exports:true*/
'use strict';
var util = require('util');
var Syntax = require('./syntax');
var utils = require('jstransform/src/utils');
var parse = require('./TypeExpressionParser').parse;
var compile = require('./TypeExpressionParser').compile;
var normalize = require('./TypeExpressionParser').normalize;
function parseAndNormalize(source, name, object) {
if (/\?$/.test(source)) {
source = '?' + source.substring(0, source.length - 1);
}
try {
var ast = parse(source);
return compile(normalize(ast));
} catch (e) {
var functionName = object.id
? '`' + object.id.name + '\''
: '<anonymous>';
throw new Error(util.format('The type `%s\' specified for %s for ' +
'the function %s, on line %s, could not be parsed. The error given was: %s',
source, name, functionName, object.loc.start.line, e.message
));
}
}
function initializeSettings(state, pragmas) {
state.g.typechecks = 'typechecks' in pragmas;
state.g.staticOnly = pragmas.typechecks === 'static-only';
}
function shouldTraverseFile(state, pragmas) {
if (state.g.typechecks === undefined) {
initializeSettings(state, pragmas);
}
return state.g.typechecks;
}
function shouldTransformFile(state, pragmas) {
if (state.g.typechecks === undefined) {
initializeSettings(state, pragmas);
}
return !state.g.staticOnly && state.g.typechecks;
}
function shouldTransformFunction(node, state, pragmas, params) {
if (!shouldTransformFile(state, pragmas)) {
throw new Error(
'shouldTransformFunction should not be called if shouldTransformFile ' +
'fails'
);
}
return (params.params && params.params.length > 0) ||
params.returns ||
(node.id && /^[A-Z]/.test(node.id.name));
}
function wrapsBody() {
return true;
}
function annotates() {
return true;
}
exports.parseAndNormalize = parseAndNormalize;
exports.shouldTransformFile = shouldTransformFile;
exports.shouldTraverseFile = shouldTraverseFile;
exports.shouldTransformFunction = shouldTransformFunction;
exports.wrapsBody = wrapsBody;
exports.annotates = annotates;
exports.name = 'typechecks';