Node.js
2.34 KB
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
99
100
101
102
103
104
105
106
107
108
import wrap from './wrap.js';
import keys from './keys.js';
// used for debugging, without the noise created by
// circular references
function toJSON ( node ) {
var obj = {};
Object.keys( node ).forEach( key => {
if ( key === 'parent' || key === 'program' || key === 'keys' || key === '__wrapped' ) return;
if ( Array.isArray( node[ key ] ) ) {
obj[ key ] = node[ key ].map( toJSON );
} else if ( node[ key ] && node[ key ].toJSON ) {
obj[ key ] = node[ key ].toJSON();
} else {
obj[ key ] = node[ key ];
}
});
return obj;
}
export default class Node {
constructor ( raw, parent ) {
raw.parent = parent;
raw.program = parent.program || parent;
raw.depth = parent.depth + 1;
raw.keys = keys[ raw.type ];
raw.indentation = undefined;
for ( const key of keys[ raw.type ] ) {
wrap( raw[ key ], raw );
}
raw.program.magicString.addSourcemapLocation( raw.start );
raw.program.magicString.addSourcemapLocation( raw.end );
}
ancestor ( level ) {
let node = this;
while ( level-- ) {
node = node.parent;
if ( !node ) return null;
}
return node;
}
contains ( node ) {
while ( node ) {
if ( node === this ) return true;
node = node.parent;
}
return false;
}
findLexicalBoundary () {
return this.parent.findLexicalBoundary();
}
findNearest ( type ) {
if ( typeof type === 'string' ) type = new RegExp( `^${type}$` );
if ( type.test( this.type ) ) return this;
return this.parent.findNearest( type );
}
findScope ( functionScope ) {
return this.parent.findScope( functionScope );
}
getIndentation () {
return this.parent.getIndentation();
}
initialise ( transforms ) {
for ( var key of this.keys ) {
const value = this[ key ];
if ( Array.isArray( value ) ) {
value.forEach( node => node && node.initialise( transforms ) );
} else if ( value && typeof value === 'object' ) {
value.initialise( transforms );
}
}
}
toJSON () {
return toJSON( this );
}
toString () {
return this.program.magicString.original.slice( this.start, this.end );
}
transpile ( code, transforms ) {
for ( const key of this.keys ) {
const value = this[ key ];
if ( Array.isArray( value ) ) {
value.forEach( node => node && node.transpile( code, transforms ) );
} else if ( value && typeof value === 'object' ) {
value.transpile( code, transforms );
}
}
}
}