add support for flow declarations in scope tracking
This commit is contained in:
parent
4596ae48b8
commit
c91baee4d5
@ -7,8 +7,6 @@ export const MESSAGES = {
|
|||||||
classesIllegalSuperCall: "Direct super call is illegal in non-constructor, use super.$1() instead",
|
classesIllegalSuperCall: "Direct super call is illegal in non-constructor, use super.$1() instead",
|
||||||
classesIllegalConstructorKind: "Illegal kind for constructor method",
|
classesIllegalConstructorKind: "Illegal kind for constructor method",
|
||||||
scopeDuplicateDeclaration: "Duplicate declaration $1",
|
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",
|
settersInvalidParamLength: "Setters must have exactly one parameter",
|
||||||
settersNoRest: "Setters aren't allowed to have a rest",
|
settersNoRest: "Setters aren't allowed to have a rest",
|
||||||
noAssignmentsInForHead: "No assignments allowed in for-in/of head",
|
noAssignmentsInForHead: "No assignments allowed in for-in/of head",
|
||||||
@ -24,6 +22,10 @@ export const MESSAGES = {
|
|||||||
illegalMethodName: "Illegal method name $1",
|
illegalMethodName: "Illegal method name $1",
|
||||||
lostTrackNodePath: "We lost track of this nodes position, likely because the AST was directly manipulated",
|
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",
|
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 }`?",
|
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",
|
traverseVerifyVisitorProperty: "You passed `traverse()` a visitor object with the property $1 that has the invalid property $2",
|
||||||
|
|||||||
@ -6,6 +6,11 @@ export var metadata = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function ReferencedIdentifier(node, parent, scope, file) {
|
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;
|
if (scope.hasBinding(node.name)) return;
|
||||||
|
|
||||||
// get the closest declaration to offer as a suggestion
|
// 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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -447,6 +447,8 @@ export default class Scope {
|
|||||||
this.registerBinding("let", path);
|
this.registerBinding("let", path);
|
||||||
} else if (t.isImportDeclaration(node) || t.isExportDeclaration(node)) {
|
} else if (t.isImportDeclaration(node) || t.isExportDeclaration(node)) {
|
||||||
this.registerBinding("module", path);
|
this.registerBinding("module", path);
|
||||||
|
} else if (t.isFlowDeclaration()) {
|
||||||
|
this.registerBinding("type", path);
|
||||||
} else {
|
} else {
|
||||||
this.registerBinding("unknown", path);
|
this.registerBinding("unknown", path);
|
||||||
}
|
}
|
||||||
@ -494,7 +496,13 @@ export default class Scope {
|
|||||||
|
|
||||||
var local = this.getOwnBindingInfo(name);
|
var local = this.getOwnBindingInfo(name);
|
||||||
if (local) {
|
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;
|
if (local.identifier === id) continue;
|
||||||
|
|
||||||
this.checkBlockScopedCollisions(local, kind, name, id);
|
this.checkBlockScopedCollisions(local, kind, name, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -83,15 +83,15 @@
|
|||||||
"ArrayTypeAnnotation": ["Flow"],
|
"ArrayTypeAnnotation": ["Flow"],
|
||||||
"BooleanTypeAnnotation": ["Flow", "FlowBaseAnnotation"],
|
"BooleanTypeAnnotation": ["Flow", "FlowBaseAnnotation"],
|
||||||
"ClassImplements": ["Flow"],
|
"ClassImplements": ["Flow"],
|
||||||
"DeclareClass": ["Flow", "FlowStatement", "Statement", "FlowDeclaration"],
|
"DeclareClass": ["Flow", "FlowDeclaration", "Statement", "Declaration"],
|
||||||
"DeclareFunction": ["Flow", "FlowStatement", "Statement", "FlowDeclaration"],
|
"DeclareFunction": ["Flow", "FlowDeclaration", "Statement", "Declaration"],
|
||||||
"DeclareModule": ["Flow", "FlowStatement", "Statement", "FlowDeclaration"],
|
"DeclareModule": ["Flow", "FlowDeclaration", "Statement"],
|
||||||
"DeclareVariable": ["Flow", "FlowStatement", "Statement", "FlowDeclaration"],
|
"DeclareVariable": ["Flow", "FlowDeclaration", "Statement", "Declaration"],
|
||||||
"FunctionTypeAnnotation": ["Flow"],
|
"FunctionTypeAnnotation": ["Flow"],
|
||||||
"FunctionTypeParam": ["Flow"],
|
"FunctionTypeParam": ["Flow"],
|
||||||
"GenericTypeAnnotation": ["Flow"],
|
"GenericTypeAnnotation": ["Flow"],
|
||||||
"InterfaceExtends": ["Flow"],
|
"InterfaceExtends": ["Flow"],
|
||||||
"InterfaceDeclaration": ["Flow", "FlowStatement", "Statement", "Declaration"],
|
"InterfaceDeclaration": ["Flow", "FlowDeclaration", "Statement", "Declaration"],
|
||||||
"IntersectionTypeAnnotation": ["Flow"],
|
"IntersectionTypeAnnotation": ["Flow"],
|
||||||
"MixedTypeAnnotation": ["Flow", "FlowBaseAnnotation"],
|
"MixedTypeAnnotation": ["Flow", "FlowBaseAnnotation"],
|
||||||
"NullableTypeAnnotation": ["Flow"],
|
"NullableTypeAnnotation": ["Flow"],
|
||||||
@ -100,7 +100,7 @@
|
|||||||
"StringTypeAnnotation": ["Flow", "FlowBaseAnnotation"],
|
"StringTypeAnnotation": ["Flow", "FlowBaseAnnotation"],
|
||||||
"TupleTypeAnnotation": ["Flow"],
|
"TupleTypeAnnotation": ["Flow"],
|
||||||
"TypeofTypeAnnotation": ["Flow"],
|
"TypeofTypeAnnotation": ["Flow"],
|
||||||
"TypeAlias": ["Flow", "FlowStatement", "Statement"],
|
"TypeAlias": ["Flow", "FlowDeclaration", "Statement", "Declaration"],
|
||||||
"TypeAnnotation": ["Flow"],
|
"TypeAnnotation": ["Flow"],
|
||||||
"TypeCastExpression": ["Flow"],
|
"TypeCastExpression": ["Flow"],
|
||||||
"TypeParameterDeclaration": ["Flow"],
|
"TypeParameterDeclaration": ["Flow"],
|
||||||
|
|||||||
@ -30,6 +30,13 @@ export function getBindingIdentifiers(node: Object): Object {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getBindingIdentifiers.keys = {
|
getBindingIdentifiers.keys = {
|
||||||
|
DeclareClass: "id",
|
||||||
|
DeclareFunction: "id",
|
||||||
|
DeclareModule: "id",
|
||||||
|
DeclareVariable: "id",
|
||||||
|
InterfaceDeclaration: "id",
|
||||||
|
TypeAlias: "id",
|
||||||
|
|
||||||
ComprehensionExpression: "blocks",
|
ComprehensionExpression: "blocks",
|
||||||
ComprehensionBlock: "left",
|
ComprehensionBlock: "left",
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user