Merge pull request #3184 from babel/workaround-inference

Test and workaround inference bugs
This commit is contained in:
Amjad Masad 2015-12-18 15:33:42 -08:00
commit fdac02fa26
4 changed files with 67 additions and 3 deletions

View File

@ -48,6 +48,14 @@ function getTypeAnnotationBindingConstantViolations(path, name) {
if (constantViolations.length) {
// pick one constant from each scope which will represent the last possible
// control flow path that it could've taken/been
/* This code is broken for the following problems:
* It thinks that assignments can only happen in scopes.
* What about conditionals, if statements without block,
* or guarded assignments.
* It also checks to see if one of the assignments is in the
* same scope and uses that as the only "violation". However,
* the binding is returned by `getConstantViolationsBefore` so we for
* sure always going to return that as the only "violation".
let rawConstantViolations = constantViolations.reverse();
let visitedScopes = [];
constantViolations = [];
@ -62,7 +70,7 @@ function getTypeAnnotationBindingConstantViolations(path, name) {
constantViolations = [violation];
break;
}
}
}*/
// add back on function constant violations since we can't track calls
constantViolations = constantViolations.concat(functionConstantViolations);

View File

@ -112,7 +112,7 @@ export function BooleanLiteral() {
}
export function NullLiteral() {
return t.voidTypeAnnotation();
return t.nullLiteralTypeAnnotation();
}
export function RegExpLiteral() {

View File

@ -0,0 +1,56 @@
var traverse = require("../lib").default;
var assert = require("assert");
var parse = require("babylon").parse;
function getPath(code) {
var ast = parse(code);
var path;
traverse(ast, {
Program: function (_path) {
path = _path;
_path.stop();
}
});
return path;
}
suite("inference", function () {
suite("baseTypeStrictlyMatches", function () {
test("it should work with null", function () {
var path = getPath("var x = null; x === null").get("body")[1].get("expression");
var left = path.get("left");
var right = path.get("right");
var strictMatch = left.baseTypeStrictlyMatches(right);
assert.ok(strictMatch, "null should be equal to null");
});
test("it should work with numbers", function () {
var path = getPath("var x = 1; x === 2").get("body")[1].get("expression");
var left = path.get("left");
var right = path.get("right");
var strictMatch = left.baseTypeStrictlyMatches(right);
assert.ok(strictMatch, "null should be equal to null");
});
test("it should bail when type changes", function () {
var path = getPath("var x = 1; if (foo) x = null;else x = 3; x === 2").get("body")[2].get("expression");
var left = path.get("left");
var right = path.get("right");
var strictMatch = left.baseTypeStrictlyMatches(right);
assert.ok(!strictMatch, "type might change in if statement");
});
test("it should differentiate between null and undefined", function () {
var path = getPath("var x; x === null").get("body")[1].get("expression");
var left = path.get("left");
var right = path.get("right");
var strictMatch = left.baseTypeStrictlyMatches(right);
assert.ok(!strictMatch, "null should not match undefined");
});
});
});

View File

@ -30,7 +30,7 @@ defineType("BooleanLiteralTypeAnnotation", {
});
defineType("NullLiteralTypeAnnotation", {
aliases: ["Flow"],
aliases: ["Flow", "FlowBaseAnnotation"],
fields: {}
});