/
BinaryExpression.ts
57 lines (50 loc) · 2.18 KB
/
BinaryExpression.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
import { ObjectPath, LiteralValueOrUnknown, UNKNOWN_VALUE, EMPTY_PATH } from '../values';
import { ExecutionPathOptions } from '../ExecutionPathOptions';
import * as NodeType from './NodeType';
import { ExpressionNode, NodeBase } from './shared/Node';
import { LiteralValue } from './Literal';
const binaryOperators: {
[operator: string]: (left: LiteralValue, right: LiteralValue) => LiteralValueOrUnknown;
} = {
'==': (left, right) => left == right,
'!=': (left, right) => left != right,
'===': (left, right) => left === right,
'!==': (left, right) => left !== right,
'<': (left, right) => left < right,
'<=': (left, right) => left <= right,
'>': (left, right) => left > right,
'>=': (left, right) => left >= right,
'<<': (left: any, right: any) => left << right,
'>>': (left: any, right: any) => left >> right,
'>>>': (left: any, right: any) => left >>> right,
'+': (left: any, right: any) => left + right,
'-': (left: any, right: any) => left - right,
'*': (left: any, right: any) => left * right,
'/': (left: any, right: any) => left / right,
'%': (left: any, right: any) => left % right,
'|': (left: any, right: any) => left | right,
'^': (left: any, right: any) => left ^ right,
'&': (left: any, right: any) => left & right,
'**': (left: any, right: any) => Math.pow(left, right),
in: (left, right: any) => left in right,
instanceof: (left, right: any) => left instanceof right
};
export default class BinaryExpression extends NodeBase {
type: NodeType.tBinaryExpression;
left: ExpressionNode;
right: ExpressionNode;
operator: keyof typeof binaryOperators;
getLiteralValueAtPath(path: ObjectPath): LiteralValueOrUnknown {
if (path.length > 0) return UNKNOWN_VALUE;
const leftValue = this.left.getLiteralValueAtPath(EMPTY_PATH);
if (leftValue === UNKNOWN_VALUE) return UNKNOWN_VALUE;
const rightValue = this.right.getLiteralValueAtPath(EMPTY_PATH);
if (rightValue === UNKNOWN_VALUE) return UNKNOWN_VALUE;
const operatorFn = binaryOperators[this.operator];
if (!operatorFn) return UNKNOWN_VALUE;
return operatorFn(<LiteralValue>leftValue, <LiteralValue>rightValue);
}
hasEffectsWhenAccessedAtPath(path: ObjectPath, _options: ExecutionPathOptions) {
return path.length > 1;
}
}