add JSX support (#1001)

This commit is contained in:
Jeff Williams 2015-08-13 16:48:17 -07:00
parent 93bd06c9e2
commit 8e47e5912a
6 changed files with 91 additions and 10 deletions

View File

@ -86,7 +86,7 @@ var parserOptions = exports.parserOptions = {
forOf: true,
generators: true,
globalReturn: true,
jsx: false,
jsx: true,
modules: true,
newTarget: true,
objectLiteralComputedProperties: true,

View File

@ -40,6 +40,17 @@ exports.Syntax = {
ImportDefaultSpecifier: 'ImportDefaultSpecifier',
ImportNamespaceSpecifier: 'ImportNamespaceSpecifier',
ImportSpecifier: 'ImportSpecifier',
JSXAttribute: 'JSXAttribute',
JSXClosingElement: 'JSXClosingElement',
JSXElement: 'JSXElement',
JSXEmptyExpression: 'JSXEmptyExpression',
JSXExpressionContainer: 'JSXExpressionContainer',
JSXIdentifier: 'JSXIdentifier',
JSXMemberExpression: 'JSXMemberExpression',
JSXNamespacedName: 'JSXNamespacedName',
JSXOpeningElement: 'JSXOpeningElement',
JSXSpreadAttribute: 'JSXSpreadAttribute',
JSXText: 'JSXText',
LabeledStatement: 'LabeledStatement',
LetStatement: 'LetStatement', // TODO: update Rhino to use VariableDeclaration
Literal: 'Literal',

View File

@ -251,11 +251,8 @@ walkers[Syntax.IfStatement] = function(node, parent, state, cb) {
};
walkers[Syntax.ImportDeclaration] = function(node, parent, state, cb) {
var i;
var l;
if (node.specifiers) {
for (i = 0, l = node.specifiers.length; i < l; i++) {
for (var i = 0, l = node.specifiers.length; i < l; i++) {
cb(node.specifiers[i], node, state);
}
}
@ -275,6 +272,62 @@ walkers[Syntax.ImportNamespaceSpecifier] = walkers[Syntax.ImportDefaultSpecifier
walkers[Syntax.ImportSpecifier] = walkers[Syntax.ExportSpecifier];
walkers[Syntax.JSXAttribute] = function(node, parent, state, cb) {
cb(node.name, node, state);
cb(node.value, node, state);
};
walkers[Syntax.JSXClosingElement] = function(node, parent, state, cb) {
cb(node.name, node, state);
};
walkers[Syntax.JSXElement] = function(node, parent, state, cb) {
cb(node.openingElement, node, state);
if (node.closingElement) {
cb(node.closingElement, node, state);
}
for (var i = 0, l = node.children.length; i < l; i++) {
cb(node.children[i], node, state);
}
};
walkers[Syntax.JSXEmptyExpression] = leafNode;
walkers[Syntax.JSXExpressionContainer] = function(node, parent, state, cb) {
cb(node.expression, node, state);
};
walkers[Syntax.JSXIdentifier] = leafNode;
walkers[Syntax.JSXMemberExpression] = function(node, parent, state, cb) {
cb(node.object, node, state);
cb(node.property. node, state);
};
walkers[Syntax.JSXNamespacedName] = function(node, parent, state, cb) {
cb(node.namespace, node, state);
cb(node.name, node, state);
};
walkers[Syntax.JSXOpeningElement] = function(node, parent, state, cb) {
cb(node.name, node, state);
for (var i = 0, l = node.attributes.length; i < l; i++) {
cb(node.attributes[i], node, state);
}
};
walkers[Syntax.JSXSpreadAttribute] = function(node, parent, state, cb) {
cb(node.argument, node, state);
};
walkers[Syntax.JSXText] = leafNode;
walkers[Syntax.LabeledStatement] = function(node, parent, state, cb) {
cb(node.body, node, state);
};

2
test/fixtures/jsx.js vendored Normal file
View File

@ -0,0 +1,2 @@
var myDivElement = <div className="foo" />;
React.render(myDivElement, document.getElementById('example'));

View File

@ -0,0 +1,17 @@
'use strict';
if (jasmine.jsParser !== 'rhino') {
describe('JSX support', function() {
it('should parse JSX files without errors', function() {
var logger = require('jsdoc/util/logger');
function parseJsx() {
return jasmine.getDocSetFromFile('test/fixtures/jsx.js');
}
spyOn(logger, 'error');
expect(parseJsx).not.toThrow();
expect(logger.error).not.toHaveBeenCalled();
});
});
}

View File

@ -8,14 +8,12 @@ describe('jsdoc/src/syntax', function() {
expect(typeof Syntax).toBe('object');
});
it('should define all of the non-JSX node types that are defined by Espree', function() {
it('should define all of the node types that are defined by Espree', function() {
var espreeSyntax = require('espree').Syntax;
Object.keys(espreeSyntax).forEach(function(nodeType) {
if (nodeType.indexOf('JSX') !== 0) {
expect(Syntax[nodeType]).toBeDefined();
expect(Syntax[nodeType]).toBe(espreeSyntax[nodeType]);
}
});
});