-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
ObjectExpression.js
80 lines (65 loc) · 3.21 KB
/
ObjectExpression.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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import Node from '../Node.js';
import { UNKNOWN_KEY } from '../variables/StructuredAssignmentTracker';
const PROPERTY_KINDS_READ = [ 'init', 'get' ];
const PROPERTY_KINDS_WRITE = [ 'init', 'set' ];
export default class ObjectExpression extends Node {
bindAssignmentAtPath ( path, expression, options ) {
if ( path.length === 0 ) return;
const { properties, hasCertainHit } = this._getPossiblePropertiesWithName(
path[ 0 ], path.length === 1 ? PROPERTY_KINDS_WRITE : PROPERTY_KINDS_READ );
(path.length === 1 || hasCertainHit)
&& properties.forEach( property => (path.length > 1 || property.kind === 'set')
&& property.bindAssignmentAtPath( path.slice( 1 ), expression, options ) );
}
forEachReturnExpressionWhenCalledAtPath ( path, callOptions, callback, options ) {
if ( path.length === 0 ) return;
const { properties, hasCertainHit } = this._getPossiblePropertiesWithName( path[ 0 ], PROPERTY_KINDS_READ );
hasCertainHit && properties.forEach( property =>
property.forEachReturnExpressionWhenCalledAtPath( path.slice( 1 ), callOptions, callback, options ) );
}
_getPossiblePropertiesWithName ( name, kinds ) {
if ( name === UNKNOWN_KEY ) {
return { properties: this.properties, hasCertainHit: false };
}
const properties = [];
let hasCertainHit = false;
for ( let index = this.properties.length - 1; index >= 0; index-- ) {
const property = this.properties[ index ];
if ( kinds.indexOf( property.kind ) < 0 ) continue;
if ( property.computed ) {
properties.push( property );
} else if ( property.key.name === name ) {
properties.push( property );
hasCertainHit = true;
break;
}
}
return { properties, hasCertainHit };
}
hasEffectsWhenAccessedAtPath ( path, options ) {
if ( path.length === 0 ) return false;
const { properties, hasCertainHit } = this._getPossiblePropertiesWithName( path[ 0 ], PROPERTY_KINDS_READ );
return (path.length > 1 && !hasCertainHit)
|| properties.some( property => property.hasEffectsWhenAccessedAtPath( path.slice( 1 ), options ) );
}
hasEffectsWhenAssignedAtPath ( path, options ) {
if ( path.length === 0 ) return false;
const { properties, hasCertainHit } = this._getPossiblePropertiesWithName(
path[ 0 ], path.length === 1 ? PROPERTY_KINDS_WRITE : PROPERTY_KINDS_READ );
return (path.length > 1 && !hasCertainHit)
|| properties.some( property => (path.length > 1 || property.kind === 'set')
&& property.hasEffectsWhenAssignedAtPath( path.slice( 1 ), options ) );
}
hasEffectsWhenCalledAtPath ( path, callOptions, options ) {
if ( path.length === 0 ) return true;
const { properties, hasCertainHit } = this._getPossiblePropertiesWithName( path[ 0 ], PROPERTY_KINDS_READ );
return !hasCertainHit || properties.some( property =>
property.hasEffectsWhenCalledAtPath( path.slice( 1 ), callOptions, options ) );
}
someReturnExpressionWhenCalledAtPath ( path, callOptions, predicateFunction, options ) {
if ( path.length === 0 ) return true;
const { properties, hasCertainHit } = this._getPossiblePropertiesWithName( path[ 0 ], PROPERTY_KINDS_READ );
return !hasCertainHit || properties.some( property =>
property.someReturnExpressionWhenCalledAtPath( path.slice( 1 ), callOptions, predicateFunction, options ) );
}
}