diff --git a/bin/jsx b/bin/jsx index aa6ae90ab8..3ad9f7c40a 100755 --- a/bin/jsx +++ b/bin/jsx @@ -2,7 +2,7 @@ "use strict"; var visitors = require('../vendor/fbtransform/visitors').transformVisitors; -var transform = require('../vendor/fbtransform/lib/transform').transform; +var transform = require('jstransform').transform; var propagate = require("../vendor/constants").propagate; require("commoner").resolve(function(id) { diff --git a/main.js b/main.js index e52527ffcf..16943df50f 100644 --- a/main.js +++ b/main.js @@ -2,7 +2,7 @@ var React = require('./build/modules/React'); var visitors = require('./vendor/fbtransform/visitors').transformVisitors; -var transform = require('./vendor/fbtransform/lib/transform').transform; +var transform = require('jstransform').transform; module.exports = { React: React, diff --git a/package.json b/package.json index 649555cd03..9f4d07459e 100644 --- a/package.json +++ b/package.json @@ -35,11 +35,10 @@ "test": "grunt build && grunt test" }, "dependencies": { - "base62": "~0.1.1", "commoner": "~0.8.4", - "esprima": "https://github.com/facebook/esprima/tarball/a3e0ea3979eb8d54d8bfade220c272903f928b1e", - "recast": "~0.4.8", - "source-map": "~0.1.22" + "esprima-fb": "1001.1001.1000-dev-harmony-fb", + "jstransform": "~1.0.0", + "recast": "~0.4.8" }, "devDependencies": { "browserify": "~2.24.1", diff --git a/vendor/browser-transforms.js b/vendor/browser-transforms.js index c553bf2e3e..b4ba305300 100644 --- a/vendor/browser-transforms.js +++ b/vendor/browser-transforms.js @@ -20,10 +20,10 @@ var runScripts; var headEl; -var transform = require('./fbtransform/lib/transform').transform; +var transform = require('jstransform').transform; var visitors = require('./fbtransform/visitors').transformVisitors; var transform = transform.bind(null, visitors.react); -var docblock = require('./fbtransform/lib/docblock'); +var docblock = require('jstransform/src/docblock'); exports.transform = transform; diff --git a/vendor/fbtransform/lib/docblock.js b/vendor/fbtransform/lib/docblock.js deleted file mode 100644 index 9c28a1b2ff..0000000000 --- a/vendor/fbtransform/lib/docblock.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Copyright 2013 Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -var docblockRe = /^\s*(\/\*\*(.|\n)*?\*\/)/; -var ltrimRe = /^\s*/; -/** - * @param {String} contents - * @return {String} - */ -function extract(contents) { - var match = contents.match(docblockRe); - if (match) { - return match[0].replace(ltrimRe, '') || ''; - } - return ''; -} - - -var commentStartRe = /^\/\*\*?/; -var commentEndRe = /\*\/$/; -var wsRe = /[\t ]+/g; -var stringStartRe = /(\n|^) *\*/g; -var multilineRe = /(?:^|\n) *(@[^\n]*?) *\n *([^@\n\s][^@\n]+?) *\n/g; -var propertyRe = /(?:^|\n) *@(\S+) *([^\n]*)/g; - -/** - * @param {String} contents - * @return {Array} - */ -function parse(docblock) { - docblock = docblock - .replace(commentStartRe, '') - .replace(commentEndRe, '') - .replace(wsRe, ' ') - .replace(stringStartRe, '$1'); - - // Normalize multi-line directives - var prev = ''; - while (prev != docblock) { - prev = docblock; - docblock = docblock.replace(multilineRe, "\n$1 $2\n"); - } - docblock = docblock.trim(); - - var result = []; - var match; - while (match = propertyRe.exec(docblock)) { - result.push([match[1], match[2]]); - } - - return result; -} - -/** - * Same as parse but returns an object of prop: value instead of array of paris - * If a property appers more than once the last one will be returned - * - * @param {String} contents - * @return {Object} - */ -function parseAsObject(docblock) { - var pairs = parse(docblock); - var result = {}; - for (var i = 0; i < pairs.length; i++) { - result[pairs[i][0]] = pairs[i][1]; - } - return result; -} - - -exports.extract = extract; -exports.parse = parse; -exports.parseAsObject = parseAsObject; diff --git a/vendor/fbtransform/lib/transform.js b/vendor/fbtransform/lib/transform.js deleted file mode 100644 index b7fd655465..0000000000 --- a/vendor/fbtransform/lib/transform.js +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Copyright 2013 Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/*global exports:true*/ -/*jslint node: true*/ -"use strict"; - -/** - * Syntax transfomer for javascript. Takes the source in, spits the source - * out. Tries to maintain readability and preserve whitespace and line numbers - * where posssible. - * - * Support - * - ES6 class transformation + private property munging, see ./classes.js - * - React XHP style syntax transformations, see ./react.js - * - Bolt XHP style syntax transformations, see ./bolt.js - * - * The general flow is the following: - * - Parse the source with our customized esprima-parser - * https://github.com/voloko/esprima. We have to customize the parser to - * support non-standard XHP-style syntax. We parse the source range: true - * option that forces esprima to return positions in the source within - * resulting parse tree. - * - * - Traverse resulting syntax tree, trying to apply a set of visitors to each - * node. Each visitor should provide a .test() function that tests if the - * visitor can process a given node. - * - * - Visitor is responsible for code generation for a given syntax node. - * Generated code is stored in state.g.buffer that is passed to every - * visitor. It's up to the visitor to process the code the way it sees fit. - * All of the current visitors however use both the node and the original - * source to generate transformed code. They use nodes to generate new - * code and they copy the original source, preserving whitespace and comments, - * for the parts they don't care about. - */ -var esprima = require('esprima'); - -var createState = require('./utils').createState; -var catchup = require('./utils').catchup; - -/** - * @param {object} object - * @param {function} visitor - * @param {array} path - * @param {object} state - */ -function traverse(object, path, state) { - var key, child; - - if (walker(traverse, object, path, state) === false) { - return; - } - path.unshift(object); - for (key in object) { - // skip obviously wrong attributes - if (key === 'range' || key === 'loc') { - continue; - } - if (object.hasOwnProperty(key)) { - child = object[key]; - if (typeof child === 'object' && child !== null) { - child.range && catchup(child.range[0], state); - traverse(child, path, state); - child.range && catchup(child.range[1], state); - } - } - } - path.shift(); -} - -function walker(traverse, object, path, state) { - var visitors = state.g.visitors; - for (var i = 0; i < visitors.length; i++) { - if (visitors[i].test(object, path, state)) { - return visitors[i](traverse, object, path, state); - } - } -} - -function runPass(source, visitors, options) { - var ast; - try { - ast = esprima.parse(source, { comment: true, loc: true, range: true }); - } catch (e) { - e.message = 'Parse Error: ' + e.message; - throw e; - } - var state = createState(source, options); - state.g.originalProgramAST = ast; - state.g.visitors = visitors; - - if (options.sourceMap) { - var SourceMapGenerator = require('source-map').SourceMapGenerator; - state.g.sourceMap = new SourceMapGenerator({ file: 'transformed.js' }); - } - traverse(ast, [], state); - catchup(source.length, state); - return state; -} - -/** - * Applies all available transformations to the source - * @param {array} visitors - * @param {string} source - * @param {?object} options - * @return {object} - */ -function transform(visitors, source, options) { - options = options || {}; - - var state = runPass(source, visitors, options); - var sourceMap = state.g.sourceMap; - - if (sourceMap) { - return { - sourceMap: sourceMap, - sourceMapFilename: options.filename || 'source.js', - code: state.g.buffer - }; - } else { - return { - code: state.g.buffer - }; - } -} - - -exports.transform = transform; diff --git a/vendor/fbtransform/lib/utils.js b/vendor/fbtransform/lib/utils.js deleted file mode 100644 index 0dc53ead66..0000000000 --- a/vendor/fbtransform/lib/utils.js +++ /dev/null @@ -1,332 +0,0 @@ -/** - * Copyright 2013 Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/*global exports:true*/ - -/** - * State represents the given parser state. It has a local and global parts. - * Global contains parser position, source, etc. Local contains scope based - * properties, like current class name. State should contain all the info - * required for transformation. It's the only mandatory object that is being - * passed to every function in transform chain. - * - * @param {String} source - * @param {Object} transformOptions - * @return {Object} - */ -function createState(source, transformOptions) { - return { - /** - * Name of the super class variable - * @type {String} - */ - superVar: '', - /** - * Name of the enclosing class scope - * @type {String} - */ - scopeName: '', - /** - * Global state (not affected by updateState) - * @type {Object} - */ - g: { - /** - * A set of general options that transformations can consider while doing - * a transformation: - * - * - minify - * Specifies that transformation steps should do their best to minify - * the output source when possible. This is useful for places where - * minification optimizations are possible with higher-level context - * info than what jsxmin can provide. - * - * For example, the ES6 class transform will minify munged private - * variables if this flag is set. - */ - opts: transformOptions, - /** - * Current position in the source code - * @type {Number} - */ - position: 0, - /** - * Buffer containing the result - * @type {String} - */ - buffer: '', - /** - * Indentation offset (only negative offset is supported now) - * @type {Number} - */ - indentBy: 0, - /** - * Source that is being transformed - * @type {String} - */ - source: source, - - /** - * Cached parsed docblock (see getDocblock) - * @type {object} - */ - docblock: null, - - /** - * Whether the thing was used - * @type {Boolean} - */ - tagNamespaceUsed: false, - - /** - * If using bolt xjs transformation - * @type {Boolean} - */ - isBolt: undefined, - - /** - * Whether to record source map (expensive) or not - * @type {SourceMapGenerator|null} - */ - sourceMap: null, - - /** - * Filename of the file being processed. Will be returned as a source - * attribute in the source map - */ - sourceMapFilename: 'source.js', - - /** - * Only when source map is used: last line in the source for which - * source map was generated - * @type {Number} - */ - sourceLine: 1, - - /** - * Only when source map is used: last line in the buffer for which - * source map was generated - * @type {Number} - */ - bufferLine: 1, - - /** - * The top-level Program AST for the original file. - */ - originalProgramAST: null, - - sourceColumn: 0, - bufferColumn: 0 - } - }; -} - -/** - * Updates a copy of a given state with "update" and returns an updated state. - * - * @param {Object} state - * @param {Object} update - * @return {Object} - */ -function updateState(state, update) { - return { - g: state.g, - superVar: update.superVar || state.superVar, - scopeName: update.scopeName || state.scopeName - }; -} - -/** - * Given a state fill the resulting buffer from the original source up to - * the end - * @param {Number} end - * @param {Object} state - * @param {Function?} contentTransformer Optional callback to transform newly - * added content. - */ -function catchup(end, state, contentTransformer) { - if (end < state.g.position) { - // cannot move backwards - return; - } - var source = state.g.source.substring(state.g.position, end); - var transformed = updateIndent(source, state); - if (state.g.sourceMap && transformed) { - // record where we are - state.g.sourceMap.addMapping({ - generated: { line: state.g.bufferLine, column: state.g.bufferColumn }, - original: { line: state.g.sourceLine, column: state.g.sourceColumn }, - source: state.g.sourceMapFilename - }); - - // record line breaks in transformed source - var sourceLines = source.split('\n'); - var transformedLines = transformed.split('\n'); - // Add line break mappings between last known mapping and the end of the - // added piece. So for the code piece - // (foo, bar); - // > var x = 2; - // > var b = 3; - // var c = - // only add lines marked with ">": 2, 3. - for (var i = 1; i < sourceLines.length - 1; i++) { - state.g.sourceMap.addMapping({ - generated: { line: state.g.bufferLine, column: 0 }, - original: { line: state.g.sourceLine, column: 0 }, - source: state.g.sourceMapFilename - }); - state.g.sourceLine++; - state.g.bufferLine++; - } - // offset for the last piece - if (sourceLines.length > 1) { - state.g.sourceLine++; - state.g.bufferLine++; - state.g.sourceColumn = 0; - state.g.bufferColumn = 0; - } - state.g.sourceColumn += sourceLines[sourceLines.length - 1].length; - state.g.bufferColumn += - transformedLines[transformedLines.length - 1].length; - } - state.g.buffer += - contentTransformer ? contentTransformer(transformed) : transformed; - state.g.position = end; -} - -/** - * Applies `catchup` but passing in a function that removes any non-whitespace - * characters. - */ -var re = /(\S)/g; -function stripNonWhite(value) { - return value.replace(re, function() { - return ''; - }); -} -/** - * Catches up as `catchup` but turns each non-white character into a space. - */ -function catchupWhiteSpace(end, state) { - catchup(end, state, stripNonWhite); -} - -/** - * Same as catchup but does not touch the buffer - * @param {Number} end - * @param {Object} state - */ -function move(end, state) { - // move the internal cursors - if (state.g.sourceMap) { - if (end < state.g.position) { - state.g.position = 0; - state.g.sourceLine = 1; - state.g.sourceColumn = 0; - } - - var source = state.g.source.substring(state.g.position, end); - var sourceLines = source.split('\n'); - if (sourceLines.length > 1) { - state.g.sourceLine += sourceLines.length - 1; - state.g.sourceColumn = 0; - } - state.g.sourceColumn += sourceLines[sourceLines.length - 1].length; - } - state.g.position = end; -} - -/** - * Appends a string of text to the buffer - * @param {String} string - * @param {Object} state - */ -function append(string, state) { - if (state.g.sourceMap && string) { - state.g.sourceMap.addMapping({ - generated: { line: state.g.bufferLine, column: state.g.bufferColumn }, - original: { line: state.g.sourceLine, column: state.g.sourceColumn }, - source: state.g.sourceMapFilename - }); - var transformedLines = string.split('\n'); - if (transformedLines.length > 1) { - state.g.bufferLine += transformedLines.length - 1; - state.g.bufferColumn = 0; - } - state.g.bufferColumn += - transformedLines[transformedLines.length - 1].length; - } - state.g.buffer += string; -} - -/** - * Update indent using state.indentBy property. Indent is measured in - * double spaces. Updates a single line only. - * - * @param {String} str - * @param {Object} state - * @return {String} - */ -function updateIndent(str, state) { - for (var i = 0; i < -state.g.indentBy; i++) { - str = str.replace(/(^|\n)( {2}|\t)/g, '$1'); - } - return str; -} - -/** - * Calculates indent from the beginning of the line until "start" or the first - * character before start. - * @example - * " foo.bar()" - * ^ - * start - * indent will be 2 - * - * @param {Number} start - * @param {Object} state - * @return {Number} - */ -function indentBefore(start, state) { - var end = start; - start = start - 1; - - while (start > 0 && state.g.source[start] != '\n') { - if (!state.g.source[start].match(/[ \t]/)) { - end = start; - } - start--; - } - return state.g.source.substring(start + 1, end); -} - -function getDocblock(state) { - if (!state.g.docblock) { - var docblock = require('./docblock'); - state.g.docblock = - docblock.parseAsObject(docblock.extract(state.g.source)); - } - return state.g.docblock; -} - -exports.catchup = catchup; -exports.catchupWhiteSpace = catchupWhiteSpace; -exports.append = append; -exports.move = move; -exports.updateIndent = updateIndent; -exports.indentBefore = indentBefore; -exports.updateState = updateState; -exports.createState = createState; -exports.getDocblock = getDocblock; diff --git a/vendor/fbtransform/syntax.js b/vendor/fbtransform/syntax.js index 9b7a0080fe..4c39ca0ac8 100644 --- a/vendor/fbtransform/syntax.js +++ b/vendor/fbtransform/syntax.js @@ -3,7 +3,7 @@ /*global exports:true*/ "use strict"; -var transform = require('./lib/transform').transform; +var transform = require('jstransform').transform; var visitors = require('./visitors'); /** diff --git a/vendor/fbtransform/transforms/classes.js b/vendor/fbtransform/transforms/classes.js deleted file mode 100644 index eb94a8afac..0000000000 --- a/vendor/fbtransform/transforms/classes.js +++ /dev/null @@ -1,492 +0,0 @@ -/** - * Copyright 2013 Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/*global exports:true*/ -"use strict"; - -/** - * Desugarizer for ES6 minimal class proposal. See - * http://wiki.ecmascript.org/doku.php?id=harmony:proposals - * - * Does not require any runtime. Preserves whitespace and comments. - * Supports a class declaration with methods, super calls and inheritance. - * Currently does not support for getters and setters, since there's a very - * low probability we're going to use them anytime soon. - * - * Additional features: - * - Any member with private name (the name with prefix _, such _name) inside - * the class's scope will be munged. This would will to eliminate the case - * of sub-class accidentally overriding the super-class's provate properties - * also discouage people from accessing private members that they should not - * access. However, quoted property names don't get munged. - * - * class SkinnedMesh extends require('THREE').Mesh { - * - * update(camera) { - * camera.code = 'iphone' - * super.update(camera); - * } - * - * / - * * @constructor - * / - * constructor(geometry, materials) { - * super(geometry, materials); - * - * super.update(1); - * - * this.identityMatrix = new THREE.Matrix4(); - * this.bones = []; - * this.boneMatrices = []; - * this._name = 'foo'; - * } - * - * / - * * some other code - * / - * readMore() { - * - * } - * - * _doSomething() { - * - * } - * } - * - * should be converted to - * - * var SkinnedMesh = (function() { - * var __super = require('parent').Mesh; - * - * / - * * @constructor - * / - * function SkinnedMesh(geometry, materials) { - * __super.call(this, geometry, materials); - * - * __super.prototype.update.call(this, 1); - * - * this.identityMatrix = new THREE.Matrix4(); - * this.bones = []; - * this.boneMatrices = []; - * this.$SkinnedMesh_name = 'foo'; - * } - * SkinnedMesh.prototype = Object.create(__super.prototype); - * SkinnedMesh.prototype.constructor = SkinnedMesh; - * - * / - * * @param camera - * / - * SkinnedMesh.prototype.update = function(camera) { - * camera.code = 'iphone' - * __super.prototype.update.call(this, camera); - * }; - * - * SkinnedMesh.prototype.readMore = function() { - * - * }; - * - * SkinnedMesh.prototype.$SkinnedMesh_doSomething = function() { - * - * }; - * - * return SkinnedMesh; - * })(); - * - */ -var Syntax = require('esprima').Syntax; -var base62 = require('base62'); - -var catchup = require('../lib/utils').catchup; -var append = require('../lib/utils').append; -var move = require('../lib/utils').move; -var indentBefore = require('../lib/utils').indentBefore; -var updateIndent = require('../lib/utils').updateIndent; -var updateState = require('../lib/utils').updateState; - -function findConstructorIndex(object) { - var classElements = object.body && object.body.body || []; - for (var i = 0; i < classElements.length; i++) { - if (classElements[i].type === Syntax.MethodDefinition && - classElements[i].key.name === 'constructor') { - return i; - } - } - return -1; -} - -var _mungedSymbolMaps = {}; -function getMungedName(scopeName, name, minify) { - if (minify) { - if (!_mungedSymbolMaps[scopeName]) { - _mungedSymbolMaps[scopeName] = { - symbolMap: {}, - identifierUUIDCounter: 0 - }; - } - - var symbolMap = _mungedSymbolMaps[scopeName].symbolMap; - if (!symbolMap[name]) { - symbolMap[name] = - base62.encode(_mungedSymbolMaps[scopeName].identifierUUIDCounter); - _mungedSymbolMaps[scopeName].identifierUUIDCounter++; - } - name = symbolMap[name]; - } - return '$' + scopeName + name; -} - -function shouldMungeName(scopeName, name, state) { - // only run when @preventMunge is not present in the docblock - if (state.g.preventMunge === undefined) { - var docblock = require('../lib/docblock'); - state.g.preventMunge = docblock.parseAsObject( - docblock.extract(state.g.source)).preventMunge !== undefined; - } - // Starts with only a single underscore (i.e. don't count double-underscores) - return !state.g.preventMunge && scopeName ? /^_(?!_)/.test(name) : false; -} - - -function getProtoOfPrototypeVariableName(superVar) { - return superVar + 'ProtoOfPrototype'; -} - -function getSuperKeyName(superVar) { - return superVar + 'Key'; -} - -function getSuperProtoOfPrototypeVariable(superVariableName, indent) { - var string = (indent + - 'var $proto = $superName && $superName.prototype ? ' + - '$superName.prototype : $superName;\n' - ).replace(/\$proto/g, getProtoOfPrototypeVariableName(superVariableName)) - .replace(/\$superName/g, superVariableName); - return string; -} - - -function getInheritanceSetup(superClassToken, className, indent, superName) { - var string = ''; - if (superClassToken) { - string += getStaticMethodsOnConstructorSetup(className, indent, superName); - string += getPrototypeOnConstructorSetup(className, indent, superName); - string += getConstructorPropertySetup(className, indent); - } - return string; -} - -function getStaticMethodsOnConstructorSetup(className, indent, superName) { - var string = ( indent + - 'for (var $keyName in $superName) {\n' + indent + - ' if ($superName.hasOwnProperty($keyName)) {\n' + indent + - ' $className[$keyName] = $superName[$keyName];\n' + indent + - ' }\n' + indent + - '}\n') - .replace(/\$className/g, className) - .replace(/\$keyName/g, getSuperKeyName(superName)) - .replace(/\$superName/g, superName); - return string; -} - -function getPrototypeOnConstructorSetup(className, indent, superName) { - var string = ( indent + - '$className.prototype = Object.create($protoPrototype);\n') - .replace(/\$protoPrototype/g, getProtoOfPrototypeVariableName(superName)) - .replace(/\$className/g, className); - return string; -} - -function getConstructorPropertySetup(className, indent) { - var string = ( indent + - '$className.prototype.constructor = $className;\n') - .replace(/\$className/g, className); - - return string; -} - -function getSuperConstructorSetup(superClassToken, indent, superName) { - if (!superClassToken) return ''; - var string = ( '\n' + indent + - ' if ($superName && $superName.prototype) {\n' + indent + - ' $superName.apply(this, arguments);\n' + indent + - ' }\n' + indent) - .replace(/\$superName/g, superName); - return string; -} - -function getMemberFunctionCall(superVar, propertyName, superArgs) { - var string = ( - '$superPrototype.$propertyName.call($superArguments)') - .replace(/\$superPrototype/g, getProtoOfPrototypeVariableName(superVar)) - .replace(/\$propertyName/g, propertyName) - .replace(/\$superArguments/g, superArgs); - return string; -} - -function getCallParams(classElement, state) { - var params = classElement.value.params; - if (!params.length) { - return ''; - } - return state.g.source.substring( - params[0].range[0], - params[params.length - 1].range[1]); -} - -function getSuperArguments(callExpression, state) { - var args = callExpression.arguments; - if (!args.length) { - return 'this'; - } - return 'this, ' + state.g.source.substring( - args[0].range[0], - args[args.length - 1].range[1]); -} - -// The seed is used to generate the name for an anonymous class, -// and this seed should be unique per browser's session. -// The value of the seed looks like this: 1229588505.2969012. -var classIDSeed = Date.now() % (60 * 60 * 1000) + Math.random(); - -/** - * Generates a name for an anonymous class. The generated value looks like - * this: "Classkc6pcn_mniza1yvi" - * @param {String} scopeName - * @return {string} the scope name for Anonymous Class - */ -function generateAnonymousClassName(scopeName) { - classIDSeed++; - return 'Class' + - (classIDSeed).toString(36).replace('.', '_') + - (scopeName || ''); -} - -function renderMethods(traverse, object, name, path, state) { - var classElements = object.body && object.body.body || []; - - move(object.body.range[0] + 1, state); - for (var i = 0; i < classElements.length; i++) { - if (classElements[i].key.name !== 'constructor') { - catchup(classElements[i].range[0], state); - - var memberName = classElements[i].key.name; - if (shouldMungeName(state.scopeName, memberName, state)) { - memberName = getMungedName( - state.scopeName, - memberName, - state.g.opts.minify - ); - } - - var prototypeOrStatic; - if (classElements[i]['static']) { - prototypeOrStatic = ''; - } else { - prototypeOrStatic = 'prototype.'; - } - - append(name + '.' + prototypeOrStatic + memberName + ' = ', state); - renderMethod(traverse, classElements[i], null, path, state); - append(';', state); - } - move(classElements[i].range[1], state); - } - if (classElements.length) { - append('\n', state); - } - move(object.range[1], state); -} - -function renderMethod(traverse, method, name, path, state) { - append(name ? 'function ' + name + '(' : 'function(', state); - append(getCallParams(method, state) + ') {', state); - move(method.value.body.range[0] + 1, state); - traverse(method.value.body, path, state); - catchup(method.value.body.range[1] - 1, state); - append('}', state); -} - -function renderSuperClass(traverse, superClass, path, state) { - append('var ' + state.superVar + ' = ', state); - move(superClass.range[0], state); - traverse(superClass, path, state); - catchup(superClass.range[1], state); - append(';\n', state); -} - -function renderConstructor(traverse, object, name, indent, path, state) { - var classElements = object.body && object.body.body || []; - var constructorIndex = findConstructorIndex(object); - var constructor = constructorIndex === -1 ? - null : - classElements[constructorIndex]; - if (constructor) { - move(constructorIndex === 0 ? - object.body.range[0] + 1 : - classElements[constructorIndex - 1].range[1], state); - catchup(constructor.range[0], state); - renderMethod(traverse, constructor, name, path, state); - append('\n', state); - } else { - if (object.superClass) { - append('\n' + indent, state); - } - append('function ', state); - if (object.id) { - move(object.id.range[0], state); - } - append(name, state); - if (object.id) { - move(object.id.range[1], state); - } - append('(){ ', state); - if (object.body) { - move(object.body.range[0], state); - } - append(getSuperConstructorSetup( - object.superClass, - indent, - state.superVar), state); - append('}\n', state); - } -} - -var superId = 0; -function renderClassBody(traverse, object, path, state) { - var name = object.id ? object.id.name : 'constructor'; - var superClass = object.superClass; - var indent = updateIndent( - indentBefore(object.range[0], state) + ' ', - state); - - state = updateState( - state, - { - scopeName: object.id ? object.id.name : - generateAnonymousClassName(state.scopeName), - superVar: superClass ? '__super' + superId++ : '' - }); - - // super class - if (superClass) { - append(indent, state); - renderSuperClass(traverse, superClass, path, state); - append(getSuperProtoOfPrototypeVariable(state.superVar, indent), state); - } - - renderConstructor(traverse, object, name, indent, path, state); - append(getInheritanceSetup(superClass, name, indent, state.superVar), state); - renderMethods(traverse, object, name, path, state); -} - - -/** - * @public - */ -function visitClassExpression(traverse, object, path, state) { - var indent = updateIndent( - indentBefore(object.range[0], state) + ' ', - state); - var name = object.id ? object.id.name : 'constructor'; - - append('(function() {\n', state); - renderClassBody(traverse, object, path, state); - append(indent + 'return ' + name + ';\n', state); - append(indent.substring(0, indent.length - 2) + '})()', state); - return false -} - -visitClassExpression.test = function(object, path, state) { - return object.type === Syntax.ClassExpression; -}; - -/** - * @public - */ -function visitClassDeclaration(traverse, object, path, state) { - state.g.indentBy--; - renderClassBody(traverse, object, path, state); - state.g.indentBy++; - return false; -} - -visitClassDeclaration.test = function(object, path, state) { - return object.type === Syntax.ClassDeclaration; -}; - - -/** - * @public - */ -function visitSuperCall(traverse, object, path, state) { - if (path[0].type === Syntax.CallExpression) { - append(state.superVar + - '.call(' + getSuperArguments(path[0], state) + ')', state); - move(path[0].range[1], state); - } else if (path[0].type === Syntax.MemberExpression) { - append(getMemberFunctionCall( - state.superVar, - path[0].property.name, - getSuperArguments(path[1], state)), state); - move(path[1].range[1], state); - } - return false; -} - -visitSuperCall.test = function(object, path, state) { - return state.superVar && object.type === Syntax.Identifier && - object.name === 'super'; -}; - -/** - * @public - */ -function visitPrivateProperty(traverse, object, path, state) { - var type = path[0] ? path[0].type : null; - if (type !== Syntax.Property) { - if (type === Syntax.MemberExpression) { - type = path[0].object ? path[0].object.type : null; - if (type === Syntax.Identifier && - path[0].object.range[0] === object.range[0]) { - // Identifier is a variable that appears "private". - return; - } - } else { - // Other syntax that are neither Property nor MemberExpression. - return; - } - } - - var oldName = object.name; - var newName = getMungedName( - state.scopeName, - oldName, - state.g.opts.minify - ); - append(newName, state); - move(object.range[1], state); -} - -visitPrivateProperty.test = function(object, path, state) { - return object.type === Syntax.Identifier && - shouldMungeName(state.scopeName, object.name, state); -}; - - -exports.visitClassDeclaration = visitClassDeclaration; -exports.visitClassExpression = visitClassExpression; -exports.visitSuperCall = visitSuperCall; -exports.visitPrivateProperty = visitPrivateProperty; diff --git a/vendor/fbtransform/transforms/react.js b/vendor/fbtransform/transforms/react.js index 502bf5cb79..bd18ace668 100644 --- a/vendor/fbtransform/transforms/react.js +++ b/vendor/fbtransform/transforms/react.js @@ -16,12 +16,12 @@ /*global exports:true*/ "use strict"; -var Syntax = require('esprima').Syntax; +var Syntax = require('esprima-fb').Syntax; -var catchup = require('../lib/utils').catchup; -var append = require('../lib/utils').append; -var move = require('../lib/utils').move; -var getDocblock = require('../lib/utils').getDocblock; +var catchup = require('jstransform/src/utils').catchup; +var append = require('jstransform/src/utils').append; +var move = require('jstransform/src/utils').move; +var getDocblock = require('jstransform/src/utils').getDocblock; var FALLBACK_TAGS = require('./xjs').knownTags; var renderXJSExpressionContainer = diff --git a/vendor/fbtransform/transforms/reactDisplayName.js b/vendor/fbtransform/transforms/reactDisplayName.js index 231e6e4201..b1f08b24e1 100644 --- a/vendor/fbtransform/transforms/reactDisplayName.js +++ b/vendor/fbtransform/transforms/reactDisplayName.js @@ -16,10 +16,10 @@ /*global exports:true*/ "use strict"; -var Syntax = require('esprima').Syntax; -var catchup = require('../lib/utils').catchup; -var append = require('../lib/utils').append; -var getDocblock = require('../lib/utils').getDocblock; +var Syntax = require('esprima-fb').Syntax; +var catchup = require('jstransform/src/utils').catchup; +var append = require('jstransform/src/utils').append; +var getDocblock = require('jstransform/src/utils').getDocblock; /** * Transforms the following: diff --git a/vendor/fbtransform/transforms/xjs.js b/vendor/fbtransform/transforms/xjs.js index efd0e35bd3..41f0c3ffb9 100644 --- a/vendor/fbtransform/transforms/xjs.js +++ b/vendor/fbtransform/transforms/xjs.js @@ -15,10 +15,10 @@ */ /*global exports:true*/ "use strict"; -var append = require('../lib/utils').append; -var catchup = require('../lib/utils').catchup; -var move = require('../lib/utils').move; -var Syntax = require('esprima').Syntax; +var append = require('jstransform/src/utils').append; +var catchup = require('jstransform/src/utils').catchup; +var move = require('jstransform/src/utils').move; +var Syntax = require('esprima-fb').Syntax; var knownTags = { a: true, diff --git a/vendor/fbtransform/visitors.js b/vendor/fbtransform/visitors.js index 4ad61723c7..93cba7f237 100644 --- a/vendor/fbtransform/visitors.js +++ b/vendor/fbtransform/visitors.js @@ -1,5 +1,5 @@ /*global exports:true*/ -var classes = require('./transforms/classes'); +var es6Classes = require('jstransform/visitors/es6-class-visitors').visitorList; var react = require('./transforms/react'); var reactDisplayName = require('./transforms/reactDisplayName'); @@ -7,21 +7,13 @@ var reactDisplayName = require('./transforms/reactDisplayName'); * Map from transformName => orderedListOfVisitors. */ var transformVisitors = { - 'es6-classes': [ - classes.visitClassExpression, - classes.visitClassDeclaration, - classes.visitSuperCall, - classes.visitPrivateProperty + 'es6-classes': es6Classes, + 'react': [ + react.visitReactTag, + reactDisplayName.visitReactDisplayName ] }; -transformVisitors.react = transformVisitors[ - "es6-classes" -].concat([ - react.visitReactTag, - reactDisplayName.visitReactDisplayName -]); - /** * Specifies the order in which each transform should run. */