Compare commits

...

29 Commits

Author SHA1 Message Date
Sebastian McKenzie
5c9d564339 v5.6.6 2015-06-24 23:27:44 +01:00
Sebastian McKenzie
031a61515b add labels, and inX properties to lookahead getState 2015-06-24 23:26:59 +01:00
Sebastian McKenzie
d3884fd53b add inType assignment in flow parse declare method 2015-06-24 23:26:48 +01:00
Sebastian McKenzie
c6eef3080e add 5.6.6 changelog 2015-06-24 23:26:35 +01:00
Sebastian McKenzie
25be0a974d fixing linting errors 2015-06-24 23:20:03 +01:00
Sebastian McKenzie
7ccd135e83 fix isKeyword flow overload 2015-06-24 23:18:21 +01:00
Sebastian McKenzie
4fc1bbeb60 acorn resync 2015-06-24 23:15:27 +01:00
Sebastian McKenzie
32a4d7172b optimise generator for compact mode 2015-06-24 23:15:22 +01:00
Sebastian McKenzie
aa25903c05 parse void as an identifier when inside a type annotation to avoid setting void keyword token - cc @DmitrySoshnikov 2015-06-24 23:15:00 +01:00
Sebastian McKenzie
23ec1a455e upgrade babel-plugin-dead-code-elimination 2015-06-24 23:14:08 +01:00
Sebastian McKenzie
e6ac2d049b add 5.6.5 changelog 2015-06-24 13:50:53 +01:00
Sebastian McKenzie
084ae31816 5.6.5 2015-06-24 13:48:43 +01:00
Sebastian McKenzie
8e530afd78 v5.6.5 2015-06-24 13:47:54 +01:00
Sebastian McKenzie
6c66a82b37 Merge branch 'master' of github.com:babel/babel 2015-06-24 13:46:05 +01:00
Sebastian McKenzie
737abca3a9 use this.space() instead of manually pushing 2015-06-24 13:45:56 +01:00
Sebastian McKenzie
9db43ca7a9 clean up t.isReferenced 2015-06-24 13:45:48 +01:00
Sebastian McKenzie
25b0683316 add Path#couldBeBaseType 2015-06-24 13:45:32 +01:00
Sebastian McKenzie
a096f6b1c5 fix noOptimise state being incorrect when recursing into multiple nested functions - fixes #1815 2015-06-24 13:45:14 +01:00
Sebastian McKenzie
e41ab2ab0c Merge pull request #1807 from benjamn/patch-1
Update Regenerator dependency to 0.8.31.
2015-06-23 17:07:25 +01:00
Ben Newman
6a6764fa7b Update Regenerator dependency to 0.8.31.
Fixes #1805.
2015-06-23 12:06:48 -04:00
Sebastian McKenzie
a2358d6863 5.6.4 2015-06-22 20:39:14 +01:00
Sebastian McKenzie
612ef79d35 v5.6.4 2015-06-22 20:38:12 +01:00
Sebastian McKenzie
2dfa6ddf36 add 5.6.4 changelog 2015-06-22 20:37:00 +01:00
Sebastian McKenzie
2910d4f82c fix Program can only be replaced with another Program error 2015-06-22 20:36:34 +01:00
Sebastian McKenzie
4b6c954f5e add ParenthesizedExpression node type for plugins to generate 2015-06-22 20:36:12 +01:00
Sebastian McKenzie
b7e23e3410 5.6.3 2015-06-22 11:57:53 +01:00
Sebastian McKenzie
a19f10e124 v5.6.3 2015-06-22 11:56:46 +01:00
Sebastian McKenzie
8e1f134635 fix rest parameter array allocation loop being incorrectly aliased - fixes #1800 2015-06-22 11:54:57 +01:00
Sebastian McKenzie
aa151016f5 5.6.2 2015-06-22 00:10:56 +01:00
31 changed files with 272 additions and 85 deletions

View File

@@ -13,6 +13,34 @@ _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.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**
* Fix rest parameter array allocation loop being incorrectly aliased.
## 5.6.2
* **Bug Fix**
* Fix method key literals not turning into computed member expression in loose mode.
* Elect rest parameters in spread element position as candidates instead of replacing them in place.
## 5.6.0
* **Bug Fix**

View File

@@ -1,7 +1,7 @@
{
"name": "babel-core",
"description": "A compiler for writing next generation JavaScript",
"version": "5.6.2",
"version": "5.6.6",
"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",

View File

@@ -1,14 +1,14 @@
{
"name": "babel",
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
"version": "5.6.1",
"version": "5.6.5",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
"license": "MIT",
"repository": "babel/babel",
"preferGlobal": true,
"dependencies": {
"babel-core": "^5.6.1",
"babel-core": "^5.6.5",
"chokidar": "^1.0.0",
"commander": "^2.6.0",
"convert-source-map": "^1.1.0",

View File

@@ -1,7 +1,7 @@
{
"name": "babel-runtime",
"description": "babel selfContained runtime",
"version": "5.6.1",
"version": "5.6.5",
"license": "MIT",
"repository": "babel/babel",
"author": "Sebastian McKenzie <sebmck@gmail.com>",

View File

@@ -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)) {

View File

@@ -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
};

View File

@@ -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

View File

@@ -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")

View File

@@ -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) {

View File

@@ -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);
}

View File

@@ -42,7 +42,7 @@ export function _method(node, print) {
}
this._params(value, print);
this.push(" ");
this.space();
print.plain(value.body);
}

View File

@@ -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;
}

View File

@@ -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(",");
}

View File

@@ -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("(");
}

View File

@@ -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);
}

View File

@@ -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);
}
}
@@ -100,7 +99,6 @@ export var visitor = {
}
// check and optimise for extremely common cases
var state = {
references: [],
offset: node.params.length,
@@ -135,6 +133,9 @@ export var visitor = {
state.references = state.references.concat(state.candidates);
}
// deopt shadowed functions as transforms like regenerator may try touch the allocation loop
state.deopted = state.deopted || !!node.shadow;
//
var start = t.literal(node.params.length);
@@ -173,13 +174,13 @@ export var visitor = {
LEN: len
});
if (!state.deopted) {
if (state.deopted) {
loop._blockHoist = node.params.length + 1;
node.body.body.unshift(loop);
} else {
// perform allocation at the lowest common denominator of all references
loop._blockHoist = 1;
this.getEarliestCommonAncestorFrom(state.references).getStatementParent().insertBefore(loop);
return;
}
loop._blockHoist = node.params.length + 1;
node.body.body.unshift(loop);
}
};

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -140,7 +140,7 @@ export function ObjectExpression() {
//
export function ArrayExpression () {
export function ArrayExpression() {
return t.genericTypeAnnotation(t.identifier("Array"));
}

View File

@@ -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)) {

View File

@@ -71,6 +71,7 @@
"MetaProperty": ["Expression"],
"NewExpression": ["Expression"],
"ObjectExpression": ["Expression"],
"ParenthesizedExpression": ["Expression"],
"SequenceExpression": ["Expression"],
"TaggedTemplateExpression": ["Expression"],
"ThisExpression": ["Expression"],

View File

@@ -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!

View File

@@ -46,6 +46,7 @@
"Noop": [],
"ObjectExpression": ["properties"],
"ObjectPattern": ["properties", "typeAnnotation"],
"ParenthesizedExpression": ["expression"],
"Program": ["body"],
"Property": ["key", "value", "decorators"],
"RestElement": ["argument", "typeAnnotation"],

View File

@@ -11148,3 +11148,9 @@ for (var ns in fbTestFixture) {
});
}
}
test("<Foo foo={function (): void {}} />", {}, {
ecmaVersion: 6,
sourceType: "module",
plugins: { jsx: true, flow: true },
});

View File

@@ -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"});

View File

@@ -0,0 +1,7 @@
var fn = async (...rest) => rest;
var fn = async (...rest) => {
if (true) {
rest;
}
};

View File

@@ -0,0 +1,39 @@
"use strict";
var _this = this;
var fn = function fn() {
for (var _len = arguments.length, rest = Array(_len), _key = 0; _key < _len; _key++) {
rest[_key] = arguments[_key];
}
return regeneratorRuntime.async(function fn$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
return context$1$0.abrupt("return", rest);
case 1:
case "end":
return context$1$0.stop();
}
}, null, _this);
};
var fn = function fn() {
for (var _len2 = arguments.length, rest = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
rest[_key2] = arguments[_key2];
}
return regeneratorRuntime.async(function fn$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
if (true) {
rest;
}
case 1:
case "end":
return context$1$0.stop();
}
}, null, _this);
};

View File

@@ -0,0 +1,3 @@
{
"stage": 0
}

View File

@@ -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);
};
}

View File

@@ -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);
};
}