add support for flow declarations in scope tracking

This commit is contained in:
Sebastian McKenzie 2015-06-08 00:04:17 +01:00
parent 4596ae48b8
commit c91baee4d5
5 changed files with 31 additions and 9 deletions

View File

@ -7,8 +7,6 @@ export const MESSAGES = {
classesIllegalSuperCall: "Direct super call is illegal in non-constructor, use super.$1() instead",
classesIllegalConstructorKind: "Illegal kind for constructor method",
scopeDuplicateDeclaration: "Duplicate declaration $1",
undeclaredVariable: "Reference to undeclared variable $1",
undeclaredVariableSuggestion: "Reference to undeclared variable $1 - did you mean $2?",
settersInvalidParamLength: "Setters must have exactly one parameter",
settersNoRest: "Setters aren't allowed to have a rest",
noAssignmentsInForHead: "No assignments allowed in for-in/of head",
@ -24,6 +22,10 @@ export const MESSAGES = {
illegalMethodName: "Illegal method name $1",
lostTrackNodePath: "We lost track of this nodes position, likely because the AST was directly manipulated",
undeclaredVariable: "Reference to undeclared variable $1",
undeclaredVariableType: "Referencing a type alias outside of a type annotation",
undeclaredVariableSuggestion: "Reference to undeclared variable $1 - did you mean $2?",
traverseNeedsParent: "Must pass a scope and parentPath unless traversing a Program/File got a $1 node",
traverseVerifyRootFunction: "You passed `traverse()` a function when it expected a visitor object, are you sure you didn't mean `{ enter: Function }`?",
traverseVerifyVisitorProperty: "You passed `traverse()` a visitor object with the property $1 that has the invalid property $2",

View File

@ -6,6 +6,11 @@ export var metadata = {
};
export function ReferencedIdentifier(node, parent, scope, file) {
var binding = scope.getBinding(node.name);
if (binding && binding.kind === "type" && !this.parentPath.isFlow()) {
throw this.errorWithNode(messages.get("undeclaredVariableType", node.name), ReferenceError);
}
if (scope.hasBinding(node.name)) return;
// get the closest declaration to offer as a suggestion
@ -34,5 +39,5 @@ export function ReferencedIdentifier(node, parent, scope, file) {
//
throw file.errorWithNode(node, msg, ReferenceError);
throw this.errorWithNode(msg, ReferenceError);
}

View File

@ -447,6 +447,8 @@ export default class Scope {
this.registerBinding("let", path);
} else if (t.isImportDeclaration(node) || t.isExportDeclaration(node)) {
this.registerBinding("module", path);
} else if (t.isFlowDeclaration()) {
this.registerBinding("type", path);
} else {
this.registerBinding("unknown", path);
}
@ -494,7 +496,13 @@ export default class Scope {
var local = this.getOwnBindingInfo(name);
if (local) {
// don't ever let a type alias shadow a local binding
if (kind === "type") continue;
// same identifier so continue safely as we're likely trying to register it
// multiple times
if (local.identifier === id) continue;
this.checkBlockScopedCollisions(local, kind, name, id);
}

View File

@ -83,15 +83,15 @@
"ArrayTypeAnnotation": ["Flow"],
"BooleanTypeAnnotation": ["Flow", "FlowBaseAnnotation"],
"ClassImplements": ["Flow"],
"DeclareClass": ["Flow", "FlowStatement", "Statement", "FlowDeclaration"],
"DeclareFunction": ["Flow", "FlowStatement", "Statement", "FlowDeclaration"],
"DeclareModule": ["Flow", "FlowStatement", "Statement", "FlowDeclaration"],
"DeclareVariable": ["Flow", "FlowStatement", "Statement", "FlowDeclaration"],
"DeclareClass": ["Flow", "FlowDeclaration", "Statement", "Declaration"],
"DeclareFunction": ["Flow", "FlowDeclaration", "Statement", "Declaration"],
"DeclareModule": ["Flow", "FlowDeclaration", "Statement"],
"DeclareVariable": ["Flow", "FlowDeclaration", "Statement", "Declaration"],
"FunctionTypeAnnotation": ["Flow"],
"FunctionTypeParam": ["Flow"],
"GenericTypeAnnotation": ["Flow"],
"InterfaceExtends": ["Flow"],
"InterfaceDeclaration": ["Flow", "FlowStatement", "Statement", "Declaration"],
"InterfaceDeclaration": ["Flow", "FlowDeclaration", "Statement", "Declaration"],
"IntersectionTypeAnnotation": ["Flow"],
"MixedTypeAnnotation": ["Flow", "FlowBaseAnnotation"],
"NullableTypeAnnotation": ["Flow"],
@ -100,7 +100,7 @@
"StringTypeAnnotation": ["Flow", "FlowBaseAnnotation"],
"TupleTypeAnnotation": ["Flow"],
"TypeofTypeAnnotation": ["Flow"],
"TypeAlias": ["Flow", "FlowStatement", "Statement"],
"TypeAlias": ["Flow", "FlowDeclaration", "Statement", "Declaration"],
"TypeAnnotation": ["Flow"],
"TypeCastExpression": ["Flow"],
"TypeParameterDeclaration": ["Flow"],

View File

@ -30,6 +30,13 @@ export function getBindingIdentifiers(node: Object): Object {
}
getBindingIdentifiers.keys = {
DeclareClass: "id",
DeclareFunction: "id",
DeclareModule: "id",
DeclareVariable: "id",
InterfaceDeclaration: "id",
TypeAlias: "id",
ComprehensionExpression: "blocks",
ComprehensionBlock: "left",