Remove support for flow bindings (#6528)

Flow bindings have been deprecated for a while.
The reason behind this change is that `declare var foo`
doesn't introduce a new local binding, but it represents
a global one.
This commit is contained in:
Nicolò Ribaudo 2017-11-09 21:29:04 +01:00 committed by Logan Smyth
parent 83cd3fb2c9
commit 9a231c5671
2 changed files with 25 additions and 35 deletions

View File

@ -9,12 +9,6 @@ import globals from "globals";
import * as t from "@babel/types";
import { scope as scopeCache } from "../cache";
// Number of calls to the crawl method to figure out whether we're
// somewhere inside a call that was trigerred by call. This is meant
// to be used to figure out whether a warning should be trigerred.
// See `warnOnFlowBinding`.
let _crawlCallsCount = 0;
// Recursively gathers the identifying names of a node.
function gatherNodeParts(node: Object, parts: Array) {
if (t.isModuleDeclaration(node)) {
@ -455,6 +449,8 @@ export default class Scope {
}
registerDeclaration(path: NodePath) {
if (path.isFlow()) return;
if (path.isLabeledStatement()) {
this.registerLabel(path);
} else if (path.isFunctionDeclaration()) {
@ -517,7 +513,7 @@ export default class Scope {
for (const name in ids) {
for (const id of (ids[name]: Array<Object>)) {
let local = this.getOwnBinding(name);
const local = this.getOwnBinding(name);
if (local) {
// same identifier so continue safely as we're likely trying to register it
@ -527,11 +523,6 @@ export default class Scope {
this.checkBlockScopedCollisions(local, kind, name, id);
}
// It's erroneous that we currently consider flow a binding, however, we can't
// remove it because people might be depending on it. See warning section
// in `warnOnFlowBinding`.
if (local && local.path.isFlow()) local = null;
parent.references[name] = true;
// A redeclaration of an existing variable is a modification
@ -677,16 +668,8 @@ export default class Scope {
}
crawl() {
_crawlCallsCount++;
this._crawl();
_crawlCallsCount--;
}
_crawl() {
const path = this.path;
//
this.references = Object.create(null);
this.bindings = Object.create(null);
this.globals = Object.create(null);
@ -908,28 +891,17 @@ export default class Scope {
return this.getBindingIdentifier(name) === node;
}
warnOnFlowBinding(binding) {
if (_crawlCallsCount === 0 && binding && binding.path.isFlow()) {
console.warn(`
You or one of the Babel plugins you are using are using Flow declarations as bindings.
Support for this will be removed in version 7. To find out the caller, grep for this
message and change it to a \`console.trace()\`.
`);
}
return binding;
}
getBinding(name: string) {
let scope = this;
do {
const binding = scope.getOwnBinding(name);
if (binding) return this.warnOnFlowBinding(binding);
if (binding) return binding;
} while ((scope = scope.parent));
}
getOwnBinding(name: string) {
return this.warnOnFlowBinding(this.bindings[name]);
return this.bindings[name];
}
getBindingIdentifier(name: string) {

View File

@ -2,8 +2,8 @@ import traverse from "../lib";
import assert from "assert";
import { parse } from "babylon";
function getPath(code) {
const ast = parse(code);
function getPath(code, options) {
const ast = parse(code, options);
let path;
traverse(ast, {
Program: function(_path) {
@ -73,6 +73,24 @@ describe("scope", function() {
);
});
it("declare var", function() {
assert.equal(
getPath("declare var foo;", { plugins: ["flow"] }).scope.getBinding(
"foo",
),
null,
);
});
it("declare function", function() {
assert.equal(
getPath("declare function foo(): void;", {
plugins: ["flow"],
}).scope.getBinding("foo"),
null,
);
});
it("variable constantness", function() {
assert.ok(getPath("var a = 1;").scope.getBinding("a").constant === true);
assert.ok(