forked from babel/babel
-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
scope.js
56 lines (47 loc) · 1.51 KB
/
scope.js
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
56
// @flow
import ScopeHandler, { Scope } from "../../util/scope";
import {
BIND_FLAGS_FLOW_DECLARE_FN,
type ScopeFlags,
type BindingTypes,
} from "../../util/scopeflags";
import * 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: string[] = [];
}
export default class FlowScopeHandler extends ScopeHandler<FlowScope> {
createScope(flags: ScopeFlags): FlowScope {
return new FlowScope(flags);
}
declareName(name: string, bindingType: BindingTypes, pos: number) {
const scope = this.currentScope();
if (bindingType & BIND_FLAGS_FLOW_DECLARE_FN) {
this.checkRedeclarationInScope(scope, name, bindingType, pos);
this.maybeExportDefined(scope, name);
scope.declareFunctions.push(name);
return;
}
super.declareName(...arguments);
}
isRedeclaredInScope(
scope: FlowScope,
name: string,
bindingType: BindingTypes,
): boolean {
if (super.isRedeclaredInScope(...arguments)) return true;
if (bindingType & BIND_FLAGS_FLOW_DECLARE_FN) {
return (
!scope.declareFunctions.includes(name) &&
(scope.lexical.includes(name) || scope.functions.includes(name))
);
}
return false;
}
checkLocalExport(id: N.Identifier) {
if (this.scopeStack[0].declareFunctions.indexOf(id.name) === -1) {
super.checkLocalExport(id);
}
}
}