-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
/
scope.ts
55 lines (47 loc) 路 1.56 KB
/
scope.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import type { Position } from "../../util/location";
import ScopeHandler, { Scope } from "../../util/scope";
import {
BIND_FLAGS_FLOW_DECLARE_FN,
type ScopeFlags,
type BindingTypes,
} from "../../util/scopeflags";
import type * as N from "../../types";
// Reference implementation: https://github.com/facebook/flow/blob/23aeb2a2ef6eb4241ce178fde5d8f17c5f747fb5/src/typing/env.ml#L536-L584
class FlowScope extends Scope {
// declare function foo(): type;
declareFunctions: Set<string> = new Set();
}
export default class FlowScopeHandler extends ScopeHandler<FlowScope> {
createScope(flags: ScopeFlags): FlowScope {
return new FlowScope(flags);
}
declareName(name: string, bindingType: BindingTypes, loc: Position) {
const scope = this.currentScope();
if (bindingType & BIND_FLAGS_FLOW_DECLARE_FN) {
this.checkRedeclarationInScope(scope, name, bindingType, loc);
this.maybeExportDefined(scope, name);
scope.declareFunctions.add(name);
return;
}
super.declareName(name, bindingType, loc);
}
isRedeclaredInScope(
scope: FlowScope,
name: string,
bindingType: BindingTypes,
): boolean {
if (super.isRedeclaredInScope(scope, name, bindingType)) return true;
if (bindingType & BIND_FLAGS_FLOW_DECLARE_FN) {
return (
!scope.declareFunctions.has(name) &&
(scope.lexical.has(name) || scope.functions.has(name))
);
}
return false;
}
checkLocalExport(id: N.Identifier) {
if (!this.scopeStack[0].declareFunctions.has(id.name)) {
super.checkLocalExport(id);
}
}
}