Compare commits

...

27 Commits

Author SHA1 Message Date
Sebastian McKenzie
9b27a170ae v5.5.6 2015-06-09 04:07:15 +01:00
Sebastian McKenzie
1db232da9e add 5.5.6 changelog 2015-06-09 04:06:06 +01:00
Sebastian McKenzie
4cc844f410 take into consideration assignment expressions in loop heads when replacing let references - fixes #1707 2015-06-09 04:04:14 +01:00
Sebastian McKenzie
024ae670cb fix traceur test blacklist 2015-06-09 03:48:22 +01:00
Sebastian McKenzie
429edda9c0 ignore StringIterator traceur test 2015-06-09 03:40:08 +01:00
Sebastian McKenzie
05b13b9ea3 fix mistyped parameter name of t.createTypeAnnotationBasedOnTypeof 2015-06-09 03:26:40 +01:00
Sebastian McKenzie
b7320ce400 add t.createTypeAnnotationBasedOnTypeof method 2015-06-09 03:23:28 +01:00
Sebastian McKenzie
0c37b7b973 add typeof conditional inference 2015-06-09 03:20:32 +01:00
Sebastian McKenzie
bb36dbd8d9 update to latest traceur and enable now passing tests 2015-06-09 03:20:02 +01:00
Sebastian McKenzie
2dd8c40618 heavily simplify constants transformer 2015-06-09 00:31:18 +01:00
Sebastian McKenzie
33128b0ccf remove unused declaration 2015-06-08 23:59:53 +01:00
Sebastian McKenzie
cf25424295 fix duplicate declaration 2015-06-08 23:49:00 +01:00
Sebastian McKenzie
7492074794 infer types of bindings inside of conditionals based on usage 2015-06-08 23:43:46 +01:00
Sebastian McKenzie
c4a491123e disallow line terminator after async contextual keyword - fixes #1711 2015-06-08 21:25:16 +01:00
Sebastian McKenzie
55ad88fe4e don't override types parameter 2015-06-08 14:59:19 +01:00
Sebastian McKenzie
7170dbced8 Merge branch 'master' of github.com:babel/babel 2015-06-08 14:53:54 +01:00
Sebastian McKenzie
b0971412a2 add inference for null, remove any type parameter from inferred arrays, add todo comment 2015-06-08 14:52:35 +01:00
Sebastian McKenzie
a6b374a681 save union type in _getTypeAnnotationBindingConstantViolations to prevent infinite recursion 2015-06-08 14:52:13 +01:00
Sebastian McKenzie
2d0355b3b9 merge previous bindings constantViolations and path onto new bindings constantViolations 2015-06-08 14:49:09 +01:00
Sebastian McKenzie
7fade101be move down module TypeAlias check 2015-06-08 14:47:58 +01:00
Sebastian McKenzie
0918da8569 Merge pull request #1708 from hawkrives/patch-2
Update README.md for the Slack channel
2015-06-08 12:35:08 +01:00
Hawken Rives
917db622c4 Update README.md
Switch out the gitter link for slack.
2015-06-08 20:33:09 +09:00
Sebastian McKenzie
f7ee6fbd20 move travis notifications from gitter to slack 2015-06-08 12:20:38 +01:00
Sebastian McKenzie
5899e9a0be don't consider type aliases to be a default declaration - fixes #1705 2015-06-08 12:20:30 +01:00
Sebastian McKenzie
d41cb11545 fix registerDeclaration for FlowDeclarations 2015-06-08 01:46:05 +01:00
Sebastian McKenzie
3ad909a4ae add 5.5.5 changelog 2015-06-08 01:45:56 +01:00
Sebastian McKenzie
4bafdf733c 5.5.5 2015-06-08 01:29:54 +01:00
21 changed files with 360 additions and 90 deletions

View File

@@ -11,9 +11,4 @@ before_script: "npm install -g codeclimate-test-reporter"
script: "make test-travis"
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/acf1870e9d223c65e8d5
on_success: always
on_failure: always
on_start: false
slack: babeljs:5Wy4QX13KVkGy9CnU0rmvgeK

View File

@@ -13,6 +13,16 @@ _Note: Gaps between patch versions are faulty/broken releases._
See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog.
## 5.5.6
* **Bug Fix**
* Fix `let` binding collision in loop head not properly replacing `AssignmentExpression`s.
## 5.5.5
* **Bug Fix**
* Fix `file.opts` not being set before `file.log.deprecate` was called causing a `ReferenceError` as it was checking for a property on it.
## 5.5.4
* **Bug Fix**

View File

@@ -9,7 +9,7 @@
</p>
<p align="center">
For questions and support please visit the <a href="https://gitter.im/babel/babel">gitter room</a> or <a href="http://stackoverflow.com/questions/tagged/babeljs">StackOverflow</a>. The Babel issue tracker is <strong>exclusively</strong> for bug reports and feature requests.
For questions and support please visit the <a href="https://babel-slack.herokuapp.com">slack channel</a> or <a href="http://stackoverflow.com/questions/tagged/babeljs">StackOverflow</a>. The Babel issue tracker is <strong>exclusively</strong> for bug reports and feature requests.
</p>
<p align="center">

View File

@@ -1,7 +1,7 @@
{
"name": "babel-core",
"description": "A compiler for writing next generation JavaScript",
"version": "5.5.5",
"version": "5.5.6",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
"license": "MIT",

View File

@@ -1,14 +1,14 @@
{
"name": "babel",
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
"version": "5.5.4",
"version": "5.5.5",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
"license": "MIT",
"repository": "babel/babel",
"preferGlobal": true,
"dependencies": {
"babel-core": "^5.5.4",
"babel-core": "^5.5.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.5.4",
"version": "5.5.5",
"license": "MIT",
"repository": "babel/babel",
"author": "Sebastian McKenzie <sebmck@gmail.com>",

View File

@@ -292,7 +292,7 @@ pp.parseExprAtom = function(refShorthandDefaultPos) {
//
if (this.options.features["es7.asyncFunctions"]) {
// async functions!
if (id.name === "async") {
if (id.name === "async" && !this.canInsertSemicolon()) {
// arrow functions
if (this.type === tt.parenL) {
let expr = this.parseParenAndDistinguishExpression(start, true, true)

View File

@@ -9,6 +9,7 @@ var STATE_KEYS = [
"lastTokEnd",
"lineStart",
"startLoc",
"curLine",
"endLoc",
"start",
"pos",

View File

@@ -83,10 +83,13 @@ pp.parseStatement = function(declaration, topLevel) {
return starttype === tt._import ? this.parseImport(node) : this.parseExport(node)
case tt.name:
if (this.options.features["es7.asyncFunctions"] && this.value === "async" && this.lookahead().type === tt._function) {
this.next();
this.expect(tt._function);
return this.parseFunction(node, true, false, true);
if (this.options.features["es7.asyncFunctions"] && this.value === "async") {
var lookahead = this.lookahead();
if (lookahead.type === tt._function && !this.canInsertSemicolon.call(lookahead)) {
this.next();
this.expect(tt._function);
return this.parseFunction(node, true, false, true);
}
}
// If the statement does not start with a statement keyword or a

View File

@@ -132,6 +132,7 @@ var metadataVisitor = {
var declar = this.get("declaration");
if (declar.isStatement()) {
var bindings = declar.getBindingIdentifiers();
for (var name in bindings) {
var binding = bindings[name];
formatter._addExport(name, binding);
@@ -205,7 +206,7 @@ var metadataVisitor = {
});
}
if (!t.isExportDefaultDeclaration(node)) {
if (!t.isExportDefaultDeclaration(node) && !declar.isTypeAlias()) {
var onlyDefault = node.specifiers && node.specifiers.length === 1 && t.isSpecifierDefault(node.specifiers[0]);
if (!onlyDefault) {
formatter.hasNonDefaultExports = true;

View File

@@ -116,6 +116,13 @@ function traverseReplace(node, parent, scope, remaps) {
replace(node, parent, scope, remaps);
}
if (t.isAssignmentExpression(node)) {
var ids = t.getBindingIdentifiers(node);
for (var name in ids) {
replace(ids[name], parent, scope, remaps);
}
}
scope.traverse(node, replaceVisitor, remaps);
}

View File

@@ -1,41 +1,18 @@
import * as messages from "../../../messages";
function checkPath(path, file) {
var ids = path.getBindingIdentifiers();
for (var name in ids) {
var id = ids[name];
var binding = path.scope.getBinding(name);
// no binding exists
if (!binding) continue;
export function Scope(node, parent, scope) {
for (var name in scope.bindings) {
var binding = scope.bindings[name];
// not a constant
if (binding.kind !== "const" && binding.kind !== "module") continue;
// check if the assignment id matches the constant declaration id
// if it does then it was the id used to initially declare the
// constant so we can just ignore it
if (binding.identifier === id) continue;
throw file.errorWithNode(id, messages.get("readOnly", name));
for (var violation of (binding.constantViolations: Array)) {
throw violation.errorWithNode(messages.get("readOnly", name));
}
}
}
export function AssignmentExpression(node, parent, scope, file) {
checkPath(this, file);
}
export { AssignmentExpression as UpdateExpression };
export function VariableDeclaration(node) {
if (node.kind === "const") node.kind = "let";
}
export function ForXStatement(node, parent, scope, file) {
var left = this.get("left");
if (left.isIdentifier() || left.isPattern()) {
checkPath(left, file);
}
}

View File

@@ -11,6 +11,19 @@ export function findParent(callback) {
return null;
}
/**
* Description
*/
export function getStatementParent() {
var path = this;
do {
if (Array.isArray(path.container)) {
return path;
}
} while(path = path.parentPath);
}
/**
* Description
*/

View File

@@ -223,3 +223,30 @@ export function getSource() {
return "";
}
}
/**
* Description
*/
export function willIMaybeExecutesBefore(target) {
return this._guessExecutionStatusRelativeTo(target) !== "after";
}
export function _guessExecutionStatusRelativeTo(target) {
var self = this.getStatementParent();
target = target.getStatementParent();
var targetFuncParent = target.scope.getFunctionParent();
var selfFuncParent = self.scope.getFunctionParent();
if (targetFuncParent !== selfFuncParent) {
return "function";
}
do {
if (target.container === self.container) {
return target.key > self.key ? "before" : "after";
}
} while(self = self.parentPath);
return "before";
}

View File

@@ -37,6 +37,8 @@ export function _resolve(dangerous?, resolved?): ?NodePath {
if (binding.path !== this) {
return binding.path.resolve(dangerous, resolved);
}
} else if (this.isTypeCastExpression()) {
return this.get("expression").resolve(dangerous, resolved);
} else if (dangerous && this.isMemberExpression()) {
// this is dangerous, as non-direct target assignments will mutate it's state
// making this resolution inaccurate
@@ -74,8 +76,6 @@ export function _resolve(dangerous?, resolved?): ?NodePath {
/**
* Infer the type of the current `NodePath`.
*
* NOTE: This is not cached. Use `getTypeAnnotation()` which is cached.
*/
export function getTypeAnnotation(force) {
@@ -86,11 +86,45 @@ export function getTypeAnnotation(force) {
return this.typeAnnotation = type;
}
export function _getTypeAnnotationBindingConstantViolations(name, types = []) {
export function _getTypeAnnotationBindingConstantViolations(path, name) {
var binding = this.scope.getBinding(name);
for (var constantViolation of (binding.constantViolations: Array)) {
types.push(constantViolation.getTypeAnnotation());
var types = [];
this.typeAnnotation = t.unionTypeAnnotation(types);
var functionConstantViolations = [];
var constantViolations = getConstantViolationsBefore(binding, path, functionConstantViolations);
var testType = getTypeAnnotationBasedOnConditional(path, name);
if (testType) {
var testConstantViolations = getConstantViolationsBefore(binding, testType.ifStatement);
// remove constant violations observed before the IfStatement
constantViolations = constantViolations.filter((path) => testConstantViolations.indexOf(path) < 0);
// clear current types and add in observed test type
types.push(testType.typeAnnotation);
}
if (constantViolations.length) {
// pick one constant from each scope which will represent the last possible
// control flow path that it could've taken/been
var rawConstantViolations = constantViolations.reverse();
var visitedScopes = [];
constantViolations = [];
for (let violation of (rawConstantViolations: Array)) {
if (visitedScopes.indexOf(violation.scope) >= 0) continue;
visitedScopes.push(violation.scope);
constantViolations.push(violation);
}
// add back on function constant violations since we can't track calls
constantViolations = constantViolations.concat(functionConstantViolations);
// push on inferred types of violated paths
for (let violation of (constantViolations: Array)) {
types.push(violation.getTypeAnnotation());
}
}
if (types.length) {
@@ -98,6 +132,106 @@ export function _getTypeAnnotationBindingConstantViolations(name, types = []) {
}
}
function getConstantViolationsBefore(binding, path, functions) {
var violations = binding.constantViolations.slice();
violations.unshift(binding.path);
return violations.filter((violation) => {
violation = violation.resolve();
var status = violation._guessExecutionStatusRelativeTo(path);
if (functions && status === "function") functions.push(violation);
return status === "before";
});
}
function checkBinary(name, path) {
var right = path.get("right").resolve();
var left = path.get("left").resolve();
if (left.isIdentifier({ name })) {
return right.getTypeAnnotation();
} else if (right.isIdentifier({ name })) {
return left.getTypeAnnotation();
}
//
var typeofPath;
var typePath;
if (left.isUnaryExpression({ operator: "typeof" })) {
typeofPath = left;
typePath = right;
} else if (right.isUnaryExpression({ operator: "typeof" })) {
typeofPath = right;
typePath = left;
}
if (!typePath && !typeofPath) return;
// ensure that the type path is a Literal
typePath = typePath.resolve();
if (!typePath.isLiteral()) return;
// and that it's a string so we can infer it
var typeValue = typePath.node.value;
if (typeof typeValue !== "string") return;
// and that the argument of the typeof path references us!
if (!typeofPath.get("argument").isIdentifier({ name })) return;
// turn type value into a type annotation
return t.createTypeAnnotationBasedOnTypeof(typePath.node.value);
}
function getParentConditional(path) {
var parentPath;
while (parentPath = path.parentPath) {
if (parentPath.isIfStatement() || parentPath.isConditionalExpression()) {
if (path.key === "test") {
return;
} else {
return parentPath;
}
} else {
path = parentPath;
}
}
}
function getTypeAnnotationBasedOnConditional(path, name) {
var ifStatement = getParentConditional(path);
if (!ifStatement) return;
var test = ifStatement.get("test");
var paths = [test];
var types = [];
do {
let path = paths.shift().resolve();
if (path.isLogicalExpression()) {
paths.push(path.get("left"));
paths.push(path.get("right"));
}
if (path.isBinaryExpression({ operator: "===" })) {
// todo: add in cases where operators imply a number
var type = checkBinary(name, path);
if (type) types.push(type);
}
} while(paths.length);
if (types.length) {
return {
typeAnnotation: t.createUnionTypeAnnotation(types),
ifStatement
};
} else {
return getTypeAnnotationBasedOnConditional(ifStatement, name);
}
}
/**
* todo: split up this method
*/
export function _getTypeAnnotation(force?: boolean): ?Object {
var node = this.node;
@@ -132,9 +266,7 @@ export function _getTypeAnnotation(force?: boolean): ?Object {
var id = this.get("id");
if (id.isIdentifier()) {
return this._getTypeAnnotationBindingConstantViolations(id.node.name, [
this.get("init").getTypeAnnotation()
]);
return this.get("init").getTypeAnnotation();
} else {
return;
}
@@ -151,7 +283,7 @@ export function _getTypeAnnotation(force?: boolean): ?Object {
//
if (this.isRestElement() || this.parentPath.isRestElement() || this.isArrayExpression()) {
return t.genericTypeAnnotation(t.identifier("Array"), t.typeParameterInstantiation([t.anyTypeAnnotation()]));
return t.genericTypeAnnotation(t.identifier("Array"));
}
//
@@ -186,9 +318,7 @@ export function _getTypeAnnotation(force?: boolean): ?Object {
if (binding.identifier.typeAnnotation) {
return binding.identifier.typeAnnotation;
} else {
return this._getTypeAnnotationBindingConstantViolations(node.name, [
binding.path.getTypeAnnotation()
]);
return this._getTypeAnnotationBindingConstantViolations(this, node.name);
}
}
@@ -300,6 +430,7 @@ export function _getTypeAnnotation(force?: boolean): ?Object {
if (typeof value === "string") return t.stringTypeAnnotation();
if (typeof value === "number") return t.numberTypeAnnotation();
if (typeof value === "boolean") return t.booleanTypeAnnotation();
if (value === null) return t.voidTypeAnnotation();
if (node.regex) return t.genericTypeAnnotation(t.identifier("RegExp"));
}

View File

@@ -1,5 +1,5 @@
export default class Binding {
constructor({ identifier, scope, path, kind }) {
constructor({ existing, identifier, scope, path, kind }) {
this.constantViolations = [];
this.constant = true;
@@ -12,6 +12,14 @@ export default class Binding {
this.kind = kind;
this.clearValue();
if (existing) {
this.constantViolations = [].concat(
existing.path,
existing.constantViolations,
this.constantViolations
);
}
}
/**

View File

@@ -434,19 +434,18 @@ export default class Scope {
*/
registerDeclaration(path: NodePath) {
var node = path.node;
if (t.isFunctionDeclaration(node)) {
if (path.isFunctionDeclaration()) {
this.registerBinding("hoisted", path);
} else if (t.isVariableDeclaration(node)) {
} else if (path.isVariableDeclaration()) {
var declarations = path.get("declarations");
for (var declar of (declarations: Array)) {
this.registerBinding(node.kind, declar);
this.registerBinding(path.node.kind, declar);
}
} else if (t.isClassDeclaration(node)) {
} else if (path.isClassDeclaration()) {
this.registerBinding("let", path);
} else if (t.isImportDeclaration(node) || t.isExportDeclaration(node)) {
} else if (path.isImportDeclaration() || path.isExportDeclaration()) {
this.registerBinding("module", path);
} else if (t.isFlowDeclaration()) {
} else if (path.isFlowDeclaration()) {
this.registerBinding("type", path);
} else {
this.registerBinding("unknown", path);
@@ -509,6 +508,7 @@ export default class Scope {
this.bindings[name] = new Binding({
identifier: id,
existing: local,
scope: this,
path: path,
kind: kind

View File

@@ -15,16 +15,28 @@ export function createUnionTypeAnnotation(types) {
}
}
/**
* Description
*/
export function removeTypeDuplicates(nodes) {
var generics = {};
var bases = {};
// store union type groups to circular references
var typeGroups = [];
var types = [];
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
if (!node) continue;
// detect duplicates
if (types.indexOf(node) >= 0) {
continue;
}
// this type matches anything
if (t.isAnyTypeAnnotation(node)) {
return [node];
@@ -38,7 +50,10 @@ export function removeTypeDuplicates(nodes) {
//
if (t.isUnionTypeAnnotation(node)) {
nodes = nodes.concat(node.types);
if (typeGroups.indexOf(node.types) < 0) {
nodes = nodes.concat(node.types);
typeGroups.push(node.types);
}
continue;
}
@@ -79,3 +94,23 @@ export function removeTypeDuplicates(nodes) {
return types;
}
/**
* Description
*/
export function createTypeAnnotationBasedOnTypeof(type) {
if (type === "string") {
return t.stringTypeAnnotation();
} else if (type === "number") {
return t.numberTypeAnnotation();
} else if (type === "undefined") {
return t.voidTypeAnnotation();
} else if (type === "boolean") {
return t.booleanTypeAnnotation();
} else if (type === "function") {
// todo
} else if (type === "object") {
// todo
}
}

View File

@@ -620,6 +620,63 @@ testFail("function foo(promise) { await promise; }", "Unexpected token (1:30)",
features: { "es7.asyncFunctions": true }
});
testFail("var x = async\n(x) => x + 1;", "Unexpected token (2:4)", {
ecmaVersion: 7,
features: { "es7.asyncFunctions": true }
});
test("async\nfunction foo() {}", {
type: "Program",
body: [
{
type: "ExpressionStatement",
expression: {
type: "Identifier",
name: "async",
loc: {
start: {line: 1, column: 0},
end: {line: 1, column: 5}
}
},
loc: {
start: {line: 1, column: 0},
end: {line: 1, column: 5}
}
},
{
type: "FunctionDeclaration",
id: {
type: "Identifier",
name: "foo",
loc: {
start: {line: 2, column: 9},
end: {line: 2, column: 12}
}
},
params: [],
body: {
type: "BlockStatement",
body: [],
loc: {
start: {line: 2, column: 15},
end: {line: 2, column: 17}
}
},
generator: false,
expression: false,
async: false,
loc: {
start: {line: 2, column: 0},
end: {line: 2, column: 17}
}
}
]
}, {
ecmaVersion: 7,
features: { "es7.asyncFunctions": true },
locations: true
});
test('async function foo(promise) { await promise; }', {
type: "Program",
body: [{

View File

@@ -11,17 +11,10 @@ require("./_transformation-helper")({
// weird environmental issue make these hard to test
"Modules",
// these are the responsibility of regenerator
"AsyncFunctions",
"Yield",
// these are the responsibility of core-js
"StringExtras",
"ArrayExtras",
"Collections",
// not supported
"ProperTailCalls",
// uses the old async generator proposal
"AsyncGenerators",
// these are all internal traceur tests or non-standard features
@@ -38,8 +31,30 @@ require("./_transformation-helper")({
],
ignoreTasks: [
// non-standard
"ObjectMixin",
// TODO
"Syntax/StrictKeywordsInPattern",
"Yield/GeneratorSend",
"Yield/BreakForOf",
"Yield/GeneratorThrow",
"Yield/ObjectModel",
"Yield/ReturnGenerator",
// TODO: core-js fails these
"Collections/Map",
"Collections/Set",
"ArrayExtras/From",
"ArrayExtras/FindIndex",
"ArrayExtras/Find",
"StringExtras/Includes",
"StringExtras/EndsWith",
// this tests pollutes Object.prototype which messes things up
"StringExtras/StartsWith",
// TODO
"Syntax/IsValidSimpleAssignmentTarget",
// babel has no way to check these :( TODO: add to caveats
"TemplateLiterals/TemplateObjectCaching.module",
@@ -52,11 +67,8 @@ require("./_transformation-helper")({
"Classes/ExtendStrange",
// these are the responsibility of core-js
"Symbol/GetOwnPropertySymbols",
"Spread/Type",
"Symbol/ObjectModel",
"Symbol/Inherited",
"Symbol/Object",
"Spread/NoIterator",
"Destructuring/Rest",
"Destructuring/Empty",
@@ -64,16 +76,8 @@ require("./_transformation-helper")({
// babel doesn't like non-closing comments :)
"Syntax/NoNewLineHereEndOfFile",
// traceur uses an old version of regexpu
"RegularExpression/Simple",
// class methods are still enumerable in traceur...
// TODO
"Classes/PrototypeDescriptor",
"NumericLiteral/Simple",
"Classes/Method",
// Object.mixin didn't make it into ES6
"ObjectMixin",
// Babel assumes that all code transformed is a module so this isn't necessary
"Strict",
@@ -87,6 +91,7 @@ require("./_transformation-helper")({
"GeneratorComprehension/Simple",
// yield has been added as a keyword in ES6
"Syntax/StrictKeywordsInPattern",
"Yield/YieldIdentifier",
"Syntax/StrictKeywords"
]

2
vendor/traceur vendored