/
ArrowFunctionExpression.ts
98 lines (85 loc) · 2.66 KB
/
ArrowFunctionExpression.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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import Scope from '../scopes/Scope';
import ReturnValueScope from '../scopes/ReturnValueScope';
import BlockStatement, { isBlockStatement } from './BlockStatement';
import CallOptions from '../CallOptions';
import { ExecutionPathOptions } from '../ExecutionPathOptions';
import { ForEachReturnExpressionCallback, SomeReturnExpressionCallback } from './shared/Expression';
import { PatternNode } from './shared/Pattern';
import { ExpressionNode, GenericEsTreeNode, NodeBase } from './shared/Node';
import { ObjectPath } from '../values';
import * as NodeType from './NodeType';
export default class ArrowFunctionExpression extends NodeBase {
type: NodeType.tArrowFunctionExpression;
body: BlockStatement | ExpressionNode;
params: PatternNode[];
scope: ReturnValueScope;
preventChildBlockScope: true;
bind() {
super.bind();
isBlockStatement(this.body)
? this.body.bindImplicitReturnExpressionToScope()
: this.scope.addReturnExpression(this.body);
}
createScope(parentScope: Scope) {
this.scope = new ReturnValueScope({ parent: parentScope });
}
forEachReturnExpressionWhenCalledAtPath(
path: ObjectPath,
callOptions: CallOptions,
callback: ForEachReturnExpressionCallback,
options: ExecutionPathOptions
) {
path.length === 0 &&
this.scope.forEachReturnExpressionWhenCalled(callOptions, callback, options);
}
hasEffects(_options: ExecutionPathOptions) {
return false;
}
hasEffectsWhenAccessedAtPath(path: ObjectPath, _options: ExecutionPathOptions) {
return path.length > 1;
}
hasEffectsWhenAssignedAtPath(path: ObjectPath, _options: ExecutionPathOptions) {
return path.length > 1;
}
hasEffectsWhenCalledAtPath(
path: ObjectPath,
_callOptions: CallOptions,
options: ExecutionPathOptions
): boolean {
if (path.length > 0) {
return true;
}
for (const param of this.params) {
if (param.hasEffects(options)) return true;
}
return this.body.hasEffects(options);
}
initialise() {
this.included = false;
for (const param of this.params) {
param.declare('parameter', null);
}
}
parseNode(esTreeNode: GenericEsTreeNode) {
if (esTreeNode.body.type === NodeType.BlockStatement) {
this.body = new this.context.nodeConstructors.BlockStatement(
esTreeNode.body,
this,
new Scope({ parent: this.scope })
);
}
super.parseNode(esTreeNode);
}
someReturnExpressionWhenCalledAtPath(
path: ObjectPath,
callOptions: CallOptions,
predicateFunction: SomeReturnExpressionCallback,
options: ExecutionPathOptions
): boolean {
return (
path.length > 0 ||
this.scope.someReturnExpressionWhenCalled(callOptions, predicateFunction, options)
);
}
}
ArrowFunctionExpression.prototype.preventChildBlockScope = true;