Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8c672bf4f | ||
|
|
7083ac61ff | ||
|
|
d256809120 | ||
|
|
26a19f82d2 | ||
|
|
128d3b5c91 | ||
|
|
c1a080d0ca | ||
|
|
0b1ce6c9a4 | ||
|
|
a6f04055c0 | ||
|
|
c3219e8b88 | ||
|
|
a35c863341 | ||
|
|
6f862a4c45 | ||
|
|
cf38210fd2 | ||
|
|
5c9d564339 | ||
|
|
031a61515b | ||
|
|
d3884fd53b | ||
|
|
c6eef3080e | ||
|
|
25be0a974d | ||
|
|
7ccd135e83 | ||
|
|
4fc1bbeb60 | ||
|
|
32a4d7172b | ||
|
|
aa25903c05 | ||
|
|
23ec1a455e | ||
|
|
e6ac2d049b | ||
|
|
084ae31816 | ||
|
|
8e530afd78 | ||
|
|
6c66a82b37 | ||
|
|
737abca3a9 | ||
|
|
9db43ca7a9 | ||
|
|
25b0683316 | ||
|
|
a096f6b1c5 | ||
|
|
e41ab2ab0c | ||
|
|
6a6764fa7b | ||
|
|
a2358d6863 | ||
|
|
612ef79d35 | ||
|
|
2dfa6ddf36 | ||
|
|
2910d4f82c | ||
|
|
4b6c954f5e | ||
|
|
b7e23e3410 |
26
CHANGELOG.md
26
CHANGELOG.md
@@ -13,6 +13,32 @@ _Note: Gaps between patch versions are faulty/broken releases._
|
||||
|
||||
See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog.
|
||||
|
||||
## 5.6.7
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix hoisting of `ForXStatement` `left` `var`s when inserting a block scoping IIFE.
|
||||
* **Polish**
|
||||
* Combine all leading computed property initialisers into the root object in loose mode.
|
||||
* **Internal**
|
||||
* Deprecate returning of replacement strings from visitor methods.
|
||||
|
||||
## 5.6.6
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix weird parser bug where `void` type annotations were being parsed as keywords causing the tokeniser to lose track of context.
|
||||
|
||||
## 5.6.5
|
||||
|
||||
* *Bug Fix**
|
||||
* Fix nested functions causing rest parameter optimisation to not properly detect when it should deopt on a reference.
|
||||
* **Internal**
|
||||
* Update Regenerator `0.8.31`.
|
||||
|
||||
## 5.6.4
|
||||
|
||||
* **Internal**
|
||||
* Add `ParenthesizedExpression` node type.
|
||||
|
||||
## 5.6.3
|
||||
|
||||
* **Bug Fix**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "babel-core",
|
||||
"description": "A compiler for writing next generation JavaScript",
|
||||
"version": "5.6.3",
|
||||
"version": "5.6.7",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
"license": "MIT",
|
||||
@@ -31,7 +31,7 @@
|
||||
"acorn-jsx": "^1.0.0",
|
||||
"ast-types": "~0.7.0",
|
||||
"babel-plugin-constant-folding": "^1.0.1",
|
||||
"babel-plugin-dead-code-elimination": "^1.0.1",
|
||||
"babel-plugin-dead-code-elimination": "^1.0.2",
|
||||
"babel-plugin-eval": "^1.0.1",
|
||||
"babel-plugin-inline-environment-variables": "^1.0.1",
|
||||
"babel-plugin-jscript": "^1.0.1",
|
||||
@@ -64,7 +64,7 @@
|
||||
"output-file-sync": "^1.1.0",
|
||||
"path-is-absolute": "^1.0.0",
|
||||
"private": "^0.1.6",
|
||||
"regenerator": "0.8.30",
|
||||
"regenerator": "0.8.31",
|
||||
"regexpu": "^1.1.2",
|
||||
"repeating": "^1.1.2",
|
||||
"resolve": "^1.1.6",
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"name": "babel",
|
||||
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
|
||||
"version": "5.6.2",
|
||||
"version": "5.6.6",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
"license": "MIT",
|
||||
"repository": "babel/babel",
|
||||
"preferGlobal": true,
|
||||
"dependencies": {
|
||||
"babel-core": "^5.6.2",
|
||||
"babel-core": "^5.6.6",
|
||||
"chokidar": "^1.0.0",
|
||||
"commander": "^2.6.0",
|
||||
"convert-source-map": "^1.1.0",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "babel-runtime",
|
||||
"description": "babel selfContained runtime",
|
||||
"version": "5.6.2",
|
||||
"version": "5.6.6",
|
||||
"license": "MIT",
|
||||
"repository": "babel/babel",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
Error.stackTraceLimit = Infinity;
|
||||
var acorn = require("../src/index")
|
||||
|
||||
var pp = acorn.Parser.prototype
|
||||
@@ -41,8 +42,11 @@ pp.flow_parseDeclareFunction = function (node) {
|
||||
typeNode.rest = tmp.rest
|
||||
this.expect(tt.parenR)
|
||||
|
||||
var oldInType = this.inType
|
||||
this.inType = true
|
||||
this.expect(tt.colon)
|
||||
typeNode.returnType = this.flow_parseType()
|
||||
this.inType = oldInType
|
||||
|
||||
typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation")
|
||||
id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation")
|
||||
@@ -352,12 +356,6 @@ pp.flow_parseGenericType = function (start, id) {
|
||||
return this.finishNode(node, "GenericTypeAnnotation")
|
||||
}
|
||||
|
||||
pp.flow_parseVoidType = function () {
|
||||
var node = this.startNode()
|
||||
this.expect(tt._void)
|
||||
return this.finishNode(node, "VoidTypeAnnotation")
|
||||
}
|
||||
|
||||
pp.flow_parseTypeofType = function () {
|
||||
var node = this.startNode()
|
||||
this.expect(tt._typeof)
|
||||
@@ -411,6 +409,9 @@ pp.flow_identToTypeAnnotation = function (start, node, id) {
|
||||
case "any":
|
||||
return this.finishNode(node, "AnyTypeAnnotation")
|
||||
|
||||
case "void":
|
||||
return this.finishNode(node, "VoidTypeAnnotation")
|
||||
|
||||
case "bool":
|
||||
case "boolean":
|
||||
return this.finishNode(node, "BooleanTypeAnnotation")
|
||||
@@ -524,14 +525,8 @@ pp.flow_parsePrimaryType = function () {
|
||||
return this.finishNode(node, "StringLiteralTypeAnnotation")
|
||||
|
||||
default:
|
||||
if (this.type.keyword) {
|
||||
switch (this.type.keyword) {
|
||||
case "void":
|
||||
return this.flow_parseVoidType()
|
||||
|
||||
case "typeof":
|
||||
return this.flow_parseTypeofType()
|
||||
}
|
||||
if (this.type.keyword === "typeof") {
|
||||
return this.flow_parseTypeofType()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -694,6 +689,18 @@ acorn.plugins.flow = function (instance) {
|
||||
}
|
||||
})
|
||||
|
||||
// don't consider `void` to be a keyword as then it'll use the void token type
|
||||
// and set startExpr
|
||||
instance.extend("isKeyword", function (inner) {
|
||||
return function(name) {
|
||||
if (this.inType && name === "void") {
|
||||
return false
|
||||
} else {
|
||||
return inner.call(this, name)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
instance.extend("readToken", function (inner) {
|
||||
return function(code) {
|
||||
if (this.inType && (code === 62 || code === 60)) {
|
||||
|
||||
@@ -19,7 +19,11 @@ var STATE_KEYS = [
|
||||
"exprAllowed",
|
||||
"potentialArrowAt",
|
||||
"currLine",
|
||||
"input"
|
||||
"input",
|
||||
"inType",
|
||||
"inFunction",
|
||||
"inGenerator",
|
||||
"labels"
|
||||
];
|
||||
|
||||
pp.getState = function () {
|
||||
@@ -29,6 +33,7 @@ pp.getState = function () {
|
||||
state[key] = this[key]
|
||||
}
|
||||
state.context = this.context.slice()
|
||||
state.labels = this.labels.slice()
|
||||
return state
|
||||
};
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@ import {lineBreak} from "./whitespace"
|
||||
|
||||
export function Parser(options, input, startPos) {
|
||||
this.options = options
|
||||
this.loadPlugins(this.options.plugins)
|
||||
this.sourceFile = this.options.sourceFile || null
|
||||
this.isKeyword = keywords[this.options.ecmaVersion >= 6 ? 6 : 5]
|
||||
this.isReservedWord = reservedWords[this.options.ecmaVersion]
|
||||
this.input = input
|
||||
this.loadPlugins(this.options.plugins)
|
||||
|
||||
// Set up token state
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ kw("case", beforeExpr)
|
||||
kw("catch")
|
||||
kw("continue")
|
||||
kw("debugger")
|
||||
kw("default")
|
||||
kw("default", beforeExpr)
|
||||
kw("do", {isLoop: true})
|
||||
kw("else", beforeExpr)
|
||||
kw("finally")
|
||||
|
||||
@@ -54,9 +54,10 @@ export default class Buffer {
|
||||
this.space();
|
||||
}
|
||||
|
||||
space() {
|
||||
if (this.format.compact) return;
|
||||
if (this.buf && !this.isLast(" ") && !this.isLast("\n")) {
|
||||
space(force?) {
|
||||
if (!force && this.format.compact) return;
|
||||
|
||||
if (force || this.buf && !this.isLast(" ") && !this.isLast("\n")) {
|
||||
this.push(" ");
|
||||
}
|
||||
}
|
||||
@@ -155,8 +156,12 @@ export default class Buffer {
|
||||
this.buf += str;
|
||||
}
|
||||
|
||||
endsWith(str) {
|
||||
return this.buf.slice(-str.length) === str;
|
||||
endsWith(str, buf = this.buf) {
|
||||
if (str.length === 1) {
|
||||
return buf[buf.length - 1] === str;
|
||||
} else {
|
||||
return buf.slice(-str.length) === str;
|
||||
}
|
||||
}
|
||||
|
||||
isLast(cha) {
|
||||
|
||||
@@ -2,19 +2,19 @@ import isNumber from "lodash/lang/isNumber";
|
||||
import * as t from "../../types";
|
||||
|
||||
export function UnaryExpression(node, print) {
|
||||
var hasSpace = /[a-z]$/.test(node.operator);
|
||||
var needsSpace = /[a-z]$/.test(node.operator);
|
||||
var arg = node.argument;
|
||||
|
||||
if (t.isUpdateExpression(arg) || t.isUnaryExpression(arg)) {
|
||||
hasSpace = true;
|
||||
needsSpace = true;
|
||||
}
|
||||
|
||||
if (t.isUnaryExpression(arg) && arg.operator === "!") {
|
||||
hasSpace = false;
|
||||
needsSpace = false;
|
||||
}
|
||||
|
||||
this.push(node.operator);
|
||||
if (hasSpace) this.push(" ");
|
||||
if (needsSpace) this.push(" ");
|
||||
print.plain(node.argument);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,12 @@ export function DoExpression(node, print) {
|
||||
print.plain(node.body);
|
||||
}
|
||||
|
||||
export function ParenthesizedExpression(node, print) {
|
||||
this.push("(");
|
||||
print.plain(node.expression);
|
||||
this.push(")");
|
||||
}
|
||||
|
||||
export function UpdateExpression(node, print) {
|
||||
if (node.prefix) {
|
||||
this.push(node.operator);
|
||||
@@ -77,19 +83,16 @@ export function CallExpression(node, print) {
|
||||
|
||||
this.push("(");
|
||||
|
||||
var separator = ",";
|
||||
|
||||
var isPrettyCall = node._prettyCall && !this.format.retainLines;
|
||||
var isPrettyCall = node._prettyCall && !this.format.retainLines && !this.format.compact;
|
||||
|
||||
var separator;
|
||||
if (isPrettyCall) {
|
||||
separator += "\n";
|
||||
separator = ",\n";
|
||||
this.newline();
|
||||
this.indent();
|
||||
} else {
|
||||
separator += " ";
|
||||
}
|
||||
|
||||
print.list(node.arguments, { separator: separator });
|
||||
print.list(node.arguments, { separator });
|
||||
|
||||
if (isPrettyCall) {
|
||||
this.newline();
|
||||
@@ -135,9 +138,22 @@ export function AssignmentPattern(node, print) {
|
||||
export function AssignmentExpression(node, print) {
|
||||
// todo: add cases where the spaces can be dropped when in compact mode
|
||||
print.plain(node.left);
|
||||
this.push(" ");
|
||||
|
||||
var spaces = node.operator === "in" || node.operator === "instanceof";
|
||||
this.space(spaces);
|
||||
|
||||
this.push(node.operator);
|
||||
this.push(" ");
|
||||
|
||||
if (!spaces) {
|
||||
// space is mandatory to avoid outputting <!--
|
||||
// http://javascript.spec.whatwg.org/#comment-syntax
|
||||
spaces = node.operator === "<" &&
|
||||
t.isUnaryExpression(node.right, { prefix: true, operator: "!" }) &&
|
||||
t.isUnaryExpression(node.right.argument, { prefix: true, operator: "--" });
|
||||
}
|
||||
|
||||
this.space(spaces);
|
||||
|
||||
print.plain(node.right);
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ export function _method(node, print) {
|
||||
}
|
||||
|
||||
this._params(value, print);
|
||||
this.push(" ");
|
||||
this.space();
|
||||
print.plain(value.body);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,13 +33,13 @@ export function ForStatement(node, print) {
|
||||
this.push(";");
|
||||
|
||||
if (node.test) {
|
||||
this.push(" ");
|
||||
this.space();
|
||||
print.plain(node.test);
|
||||
}
|
||||
this.push(";");
|
||||
|
||||
if (node.update) {
|
||||
this.push(" ");
|
||||
this.space();
|
||||
print.plain(node.update);
|
||||
}
|
||||
|
||||
@@ -190,16 +190,29 @@ export function VariableDeclaration(node, print, parent) {
|
||||
}
|
||||
}
|
||||
|
||||
var sep = ",";
|
||||
//
|
||||
// use a pretty separator when we aren't in compact mode, have initializers and don't have retainLines on
|
||||
// this will format declarations like:
|
||||
//
|
||||
// var foo = "bar", bar = "foo";
|
||||
//
|
||||
// into
|
||||
//
|
||||
// var foo = "bar",
|
||||
// bar = "foo";
|
||||
//
|
||||
|
||||
var sep;
|
||||
if (!this.format.compact && !this.format.concise && hasInits && !this.format.retainLines) {
|
||||
sep += `\n${repeating(" ", node.kind.length + 1)}`;
|
||||
} else {
|
||||
sep += " ";
|
||||
sep = `,\n${repeating(" ", node.kind.length + 1)}`;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
print.list(node.declarations, { separator: sep });
|
||||
|
||||
if (t.isFor(parent)) {
|
||||
// don't give semicolons to these nodes since they'll be inserted in the parent generator
|
||||
if (parent.left === node || parent.init === node) return;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ export function ArrayExpression(node, print) {
|
||||
// both (all) of the holes.
|
||||
this.push(",");
|
||||
} else {
|
||||
if (i > 0) this.push(" ");
|
||||
if (i > 0) this.space();
|
||||
print.plain(elem);
|
||||
if (i < len - 1) this.push(",");
|
||||
}
|
||||
|
||||
@@ -128,8 +128,7 @@ class CodeGenerator {
|
||||
// catch up to this nodes newline if we're behind
|
||||
if (node.loc && this.format.retainLines && this.buffer.buf) {
|
||||
var needsParens = false;
|
||||
if (!leftParenPrinted && parent &&
|
||||
this.position.line < node.loc.start.line && t.isTerminatorless(parent)) {
|
||||
if (!leftParenPrinted && parent && this.position.line < node.loc.start.line && t.isTerminatorless(parent)) {
|
||||
needsParens = true;
|
||||
this._push("(");
|
||||
}
|
||||
|
||||
@@ -18,7 +18,11 @@ export default class NodePrinter {
|
||||
}
|
||||
|
||||
list(items, opts = {}) {
|
||||
if (opts.separator == null) opts.separator = ", ";
|
||||
if (opts.separator == null) {
|
||||
opts.separator = ",";
|
||||
if (!this.generator.format.compact) opts.separator += " ";
|
||||
}
|
||||
|
||||
return this.join(items, opts);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import buildDebug from "debug/node";
|
||||
var verboseDebug = buildDebug("babel:verbose");
|
||||
var generalDebug = buildDebug("babel");
|
||||
|
||||
var seenDeprecatedMessages = [];
|
||||
|
||||
export default class Logger {
|
||||
constructor(file: File, filename: string) {
|
||||
this.filename = filename;
|
||||
@@ -25,9 +27,17 @@ export default class Logger {
|
||||
}
|
||||
|
||||
deprecate(msg) {
|
||||
if (!this.file.opts.suppressDeprecationMessages) {
|
||||
console.error(this._buildMessage(msg));
|
||||
}
|
||||
if (this.file.opts.suppressDeprecationMessages) return;
|
||||
|
||||
msg = this._buildMessage(msg);
|
||||
|
||||
// already seen this message
|
||||
if (seenDeprecatedMessages.indexOf(msg) >= 0) return;
|
||||
|
||||
// make sure we don't see it again
|
||||
seenDeprecatedMessages.push(msg);
|
||||
|
||||
console.error(msg);
|
||||
}
|
||||
|
||||
verbose(msg: string) {
|
||||
|
||||
@@ -162,6 +162,7 @@ var hoistVarDeclarationsVisitor = {
|
||||
} else if (this.isFor()) {
|
||||
if (isVar(node.left, node)) {
|
||||
node.left = node.left.declarations[0].id;
|
||||
self.pushDeclar(node.left);
|
||||
}
|
||||
} else if (isVar(node, parent)) {
|
||||
return self.pushDeclar(node).map(t.expressionStatement);
|
||||
|
||||
@@ -12,9 +12,10 @@ var memberExpressionOptimisationVisitor = {
|
||||
Function(node, parent, scope, state) {
|
||||
// skip over functions as whatever `arguments` we reference inside will refer
|
||||
// to the wrong function
|
||||
var oldNoOptimise = state.noOptimise;
|
||||
state.noOptimise = true;
|
||||
this.traverse(memberExpressionOptimisationVisitor, state);
|
||||
state.noOptimise = false;
|
||||
state.noOptimise = oldNoOptimise;
|
||||
this.skip();
|
||||
},
|
||||
|
||||
@@ -27,7 +28,9 @@ var memberExpressionOptimisationVisitor = {
|
||||
// is this a referenced identifier and is it referencing the rest parameter?
|
||||
if (node.name !== state.name) return;
|
||||
|
||||
if (!state.noOptimise) {
|
||||
if (state.noOptimise) {
|
||||
state.deopted = true;
|
||||
} else {
|
||||
if (this.parentPath.isMemberExpression({ computed: true, object: node })) {
|
||||
// if we know that this member expression is referencing a number then we can safely
|
||||
// optimise it
|
||||
@@ -46,11 +49,7 @@ var memberExpressionOptimisationVisitor = {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (state.noOptimise) {
|
||||
state.deopted = true;
|
||||
} else {
|
||||
state.references.push(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
function loose(node, body, objId) {
|
||||
for (var i = 0; i < node.properties.length; i++) {
|
||||
var prop = node.properties[i];
|
||||
for (var prop of (node.properties: Array)) {
|
||||
if (!prop) continue;
|
||||
|
||||
body.push(t.expressionStatement(
|
||||
t.assignmentExpression(
|
||||
@@ -15,32 +15,18 @@ function loose(node, body, objId) {
|
||||
}
|
||||
|
||||
function spec(node, body, objId, initProps, file) {
|
||||
var props = node.properties;
|
||||
|
||||
// add all non-computed properties and `__proto__` properties to the initializer
|
||||
|
||||
var broken = false;
|
||||
|
||||
for (let i = 0; i < props.length; i++) {
|
||||
let prop = props[i];
|
||||
|
||||
if (prop.computed) {
|
||||
broken = true;
|
||||
}
|
||||
|
||||
if (prop.kind !== "init" || !broken || t.isLiteral(t.toComputedKey(prop, prop.key), { value: "__proto__" })) {
|
||||
initProps.push(prop);
|
||||
props[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
// add a simple assignment for all Symbol member expressions due to symbol polyfill limitations
|
||||
// otherwise use Object.defineProperty
|
||||
|
||||
for (let i = 0; i < props.length; i++) {
|
||||
let prop = props[i];
|
||||
for (let prop of (node.properties: Array)) {
|
||||
if (!prop) continue;
|
||||
|
||||
// this wont work with Object.defineProperty
|
||||
if (t.isLiteral(t.toComputedKey(prop), { value: "__proto__" })) {
|
||||
initProps.push(prop);
|
||||
continue;
|
||||
}
|
||||
|
||||
let key = prop.key;
|
||||
if (t.isIdentifier(key) && !prop.computed) {
|
||||
key = t.literal(key.name);
|
||||
@@ -68,14 +54,33 @@ export var visitor = {
|
||||
exit(node, parent, scope, file) {
|
||||
var hasComputed = false;
|
||||
|
||||
for (var prop of (node.properties: Array)) {
|
||||
for (let prop of (node.properties: Array)) {
|
||||
hasComputed = t.isProperty(prop, { computed: true, kind: "init" });
|
||||
if (hasComputed) break;
|
||||
}
|
||||
|
||||
if (!hasComputed) return;
|
||||
|
||||
// put all getters/setters into the first object expression as well as all initialisers up
|
||||
// to the first computed property
|
||||
|
||||
var initProps = [];
|
||||
var stopInits = false;
|
||||
|
||||
for (var i = 0; i < node.properties.length; i++) {
|
||||
let prop = node.properties[i];
|
||||
if (prop.computed) {
|
||||
stopInits = true;
|
||||
}
|
||||
|
||||
if (prop.kind !== "init" || !stopInits) {
|
||||
initProps.push(prop);
|
||||
node.properties[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
var objId = scope.generateUidIdentifierBasedOnNode(parent);
|
||||
|
||||
//
|
||||
|
||||
@@ -230,6 +230,7 @@ export function unshiftContext(context) {
|
||||
*/
|
||||
|
||||
export function setup(parentPath, container, listKey, key) {
|
||||
this.inList = !!listKey;
|
||||
this.listKey = listKey;
|
||||
this.parentKey = listKey || key;
|
||||
this.container = container;
|
||||
|
||||
@@ -21,6 +21,7 @@ export default class NodePath {
|
||||
this.context = null;
|
||||
this.container = null;
|
||||
this.listKey = null;
|
||||
this.inList = false;
|
||||
this.parentKey = null;
|
||||
this.key = null;
|
||||
this.node = null;
|
||||
|
||||
@@ -61,9 +61,11 @@ export function _getTypeAnnotation(): ?Object {
|
||||
* Description
|
||||
*/
|
||||
|
||||
export function isBaseType(baseName: string): boolean {
|
||||
var type = this.getTypeAnnotation();
|
||||
export function isBaseType(baseName: string, soft?): boolean {
|
||||
return _isBaseType(baseName, this.getTypeAnnotation(), soft);
|
||||
}
|
||||
|
||||
function _isBaseType(baseName: string, type?, soft?): boolean {
|
||||
if (baseName === "string") {
|
||||
return t.isStringTypeAnnotation(type);
|
||||
} else if (baseName === "number") {
|
||||
@@ -75,7 +77,31 @@ export function isBaseType(baseName: string): boolean {
|
||||
} else if (baseName === "mixed") {
|
||||
return t.isMixedTypeAnnotation(type);
|
||||
} else {
|
||||
throw new Error(`Unknown base type ${baseName}`);
|
||||
if (soft) {
|
||||
return false;
|
||||
} else {
|
||||
throw new Error(`Unknown base type ${baseName}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
export function couldBeBaseType(name: string): boolean {
|
||||
var type = this.getTypeAnnotation();
|
||||
if (t.isAnyTypeAnnotation(type)) return true;
|
||||
|
||||
if (t.isUnionTypeAnnotation(type)) {
|
||||
for (var type2 of (type.types: Array)) {
|
||||
if (t.isAnyTypeAnnotation(type2) || _isBaseType(name, type2, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
return _isBaseType(name, type, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ export function ObjectExpression() {
|
||||
|
||||
//
|
||||
|
||||
export function ArrayExpression () {
|
||||
export function ArrayExpression() {
|
||||
return t.genericTypeAnnotation(t.identifier("Array"));
|
||||
}
|
||||
|
||||
|
||||
@@ -92,14 +92,14 @@ export function replaceWith(replacement, whateverAllowed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isProgram() && !t.isProgram(replacement)) {
|
||||
throw new Error("You can only replace a Program root node with another Program node");
|
||||
}
|
||||
|
||||
// normalise inserting an entire AST
|
||||
if (t.isProgram(replacement) && !this.isProgram()) {
|
||||
replacement = replacement.body;
|
||||
whateverAllowed = true;
|
||||
} else {
|
||||
if (this.isProgram()) {
|
||||
throw new Error("You can only replace a Program root node with another Program node");
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(replacement)) {
|
||||
@@ -112,6 +112,13 @@ export function replaceWith(replacement, whateverAllowed) {
|
||||
|
||||
if (typeof replacement === "string") {
|
||||
if (whateverAllowed) {
|
||||
this.hub.file.log.deprecate("Returning a string from a visitor method will be removed in the future. String " +
|
||||
"building is NOT a substitute for AST generation. String building leads to " +
|
||||
"terrible performance due to the additional parsing overhead and will lead to " +
|
||||
"extremely brittle transformers. For those extreme cases where you're dealing " +
|
||||
"with strings from a foreign source you may continue to use " +
|
||||
"`path.replaceWithSourceString(code)`. Please don't abuse this. Bad plugins " +
|
||||
"hurt the ecosystem.");
|
||||
return this.replaceWithSourceString(replacement);
|
||||
} else {
|
||||
throw new Error("Don't use `path.replaceWith()` with a string, use `path.replaceWithSourceString()`");
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
"MetaProperty": ["Expression"],
|
||||
"NewExpression": ["Expression"],
|
||||
"ObjectExpression": ["Expression"],
|
||||
"ParenthesizedExpression": ["Expression"],
|
||||
"SequenceExpression": ["Expression"],
|
||||
"TaggedTemplateExpression": ["Expression"],
|
||||
"ThisExpression": ["Expression"],
|
||||
|
||||
@@ -23,7 +23,7 @@ export function isReferenced(node: Object, parent: Object): boolean {
|
||||
switch (parent.type) {
|
||||
// yes: PARENT[NODE]
|
||||
// yes: NODE.child
|
||||
// no: parent.CHILD
|
||||
// no: parent.NODE
|
||||
case "MemberExpression":
|
||||
case "JSXMemberExpression":
|
||||
if (parent.property === node && parent.computed) {
|
||||
@@ -73,21 +73,17 @@ export function isReferenced(node: Object, parent: Object): boolean {
|
||||
return parent.local === node;
|
||||
}
|
||||
|
||||
// no: import NODE from "foo";
|
||||
case "ImportDefaultSpecifier":
|
||||
return false;
|
||||
|
||||
// no: import * as NODE from "foo";
|
||||
case "ImportNamespaceSpecifier":
|
||||
return false;
|
||||
|
||||
// no: <div NODE="foo" />
|
||||
case "JSXAttribute":
|
||||
return parent.name !== node;
|
||||
|
||||
// no: import NODE from "foo";
|
||||
// no: import * as NODE from "foo";
|
||||
// no: import { NODE as foo } from "foo";
|
||||
// no: import { foo as NODE } from "foo";
|
||||
// no: import NODE from "bar";
|
||||
case "ImportDefaultSpecifier":
|
||||
case "ImportNamespaceSpecifier":
|
||||
case "ImportSpecifier":
|
||||
return false;
|
||||
|
||||
@@ -112,12 +108,16 @@ export function isReferenced(node: Object, parent: Object): boolean {
|
||||
case "RestElement":
|
||||
return false;
|
||||
|
||||
// no: [NODE = foo] = [];
|
||||
// yes: [foo = NODE] = [];
|
||||
// yes: left = NODE;
|
||||
// no: NODE = right;
|
||||
case "AssignmentExpression":
|
||||
case "AssignmentPattern":
|
||||
return parent.right === node;
|
||||
|
||||
// no: [NODE = foo] = [];
|
||||
// no: [foo = NODE] = [];
|
||||
case "AssignmentPattern":
|
||||
return false;
|
||||
|
||||
// no: [NODE] = [];
|
||||
// no: ({ NODE }) = [];
|
||||
case "ObjectPattern":
|
||||
@@ -195,7 +195,7 @@ export function isImmutable(node: Object): boolean {
|
||||
|
||||
if (t.isLiteral(node)) {
|
||||
if (node.regex) {
|
||||
// regexes are mutable
|
||||
// regexs are mutable
|
||||
return false;
|
||||
} else {
|
||||
// immutable!
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
"Noop": [],
|
||||
"ObjectExpression": ["properties"],
|
||||
"ObjectPattern": ["properties", "typeAnnotation"],
|
||||
"ParenthesizedExpression": ["expression"],
|
||||
"Program": ["body"],
|
||||
"Property": ["key", "value", "decorators"],
|
||||
"RestElement": ["argument", "typeAnnotation"],
|
||||
|
||||
@@ -11148,3 +11148,9 @@ for (var ns in fbTestFixture) {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
test("<Foo foo={function (): void {}} />", {}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
plugins: { jsx: true, flow: true },
|
||||
});
|
||||
|
||||
@@ -15328,3 +15328,5 @@ test("({ ['__proto__']: 1, __proto__: 2 })", {}, {ecmaVersion: 6});
|
||||
test("({ __proto__() { return 1 }, __proto__: 2 })", {}, {ecmaVersion: 6});
|
||||
test("({ get __proto__() { return 1 }, __proto__: 2 })", {}, {ecmaVersion: 6});
|
||||
test("({ __proto__, __proto__: 2 })", {}, {ecmaVersion: 6});
|
||||
|
||||
test("export default /foo/", {}, {ecmaVersion: 6, sourceType: "module"});
|
||||
|
||||
@@ -41,3 +41,12 @@ function r(...rest){
|
||||
if (lol) rest;
|
||||
rest;
|
||||
}
|
||||
|
||||
// nested functions
|
||||
function a(...args) {
|
||||
return function() {
|
||||
function b() {}
|
||||
|
||||
console.log("Shouldn't args be from a's scope?", args);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -64,3 +64,16 @@ function r() {
|
||||
if (lol) rest;
|
||||
rest;
|
||||
}
|
||||
|
||||
// nested functions
|
||||
function a() {
|
||||
for (var _len6 = arguments.length, args = Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
|
||||
args[_key6] = arguments[_key6];
|
||||
}
|
||||
|
||||
return function () {
|
||||
function b() {}
|
||||
|
||||
console.log("Shouldn't args be from a's scope?", args);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
var obj = {
|
||||
foo: "bar",
|
||||
[bar]: "foo"
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
var _obj;
|
||||
|
||||
var obj = (_obj = {
|
||||
foo: "bar"
|
||||
}, _obj[bar] = "foo", _obj);
|
||||
@@ -1,3 +1,4 @@
|
||||
{
|
||||
"blacklist": ["es5.properties.mutators"],
|
||||
"loose": ["es6.properties.computed"]
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var obj = {
|
||||
first: "first",
|
||||
["second"]: "second",
|
||||
[second]: "second",
|
||||
};
|
||||
|
||||
@@ -2,4 +2,6 @@
|
||||
|
||||
var _obj;
|
||||
|
||||
var obj = (_obj = {}, _obj.first = "first", _obj["second"] = "second", _obj);
|
||||
var obj = (_obj = {
|
||||
first: "first"
|
||||
}, _obj[second] = "second", _obj);
|
||||
|
||||
Reference in New Issue
Block a user