12
12
const fs = require ( "fs" )
13
13
const path = require ( "path" )
14
14
const parser = require ( "../" )
15
+ const escope = require ( "eslint-scope" )
15
16
16
17
//------------------------------------------------------------------------------
17
18
// Helpers
@@ -38,7 +39,7 @@ function replacer(key, value) {
38
39
return undefined
39
40
}
40
41
if ( key === "errors" && Array . isArray ( value ) ) {
41
- return value . map ( e => ( {
42
+ return value . map ( ( e ) => ( {
42
43
message : e . message ,
43
44
index : e . index ,
44
45
lineNumber : e . lineNumber ,
@@ -95,6 +96,106 @@ function getTree(source, ast) {
95
96
return root . children
96
97
}
97
98
99
+ function scopeToJSON ( scopeManager ) {
100
+ return JSON . stringify ( normalizeScope ( scopeManager . globalScope ) , replacer , 4 )
101
+
102
+ function normalizeScope ( scope ) {
103
+ return {
104
+ type : scope . type ,
105
+ variables : scope . variables . map ( normalizeVar ) ,
106
+ references : scope . references . map ( normalizeReference ) ,
107
+ childScopes : scope . childScopes . map ( normalizeScope ) ,
108
+ through : scope . through . map ( normalizeReference ) ,
109
+ }
110
+ }
111
+
112
+ function normalizeVar ( v ) {
113
+ return {
114
+ name : v . name ,
115
+ identifiers : v . identifiers . map ( normalizeId ) ,
116
+ defs : v . defs . map ( normalizeDef ) ,
117
+ references : v . references . map ( normalizeReference ) ,
118
+ }
119
+ }
120
+
121
+ function normalizeReference ( reference ) {
122
+ return {
123
+ identifier : normalizeId ( reference . identifier ) ,
124
+ from : reference . from . type ,
125
+ resolved : normalizeId (
126
+ reference . resolved &&
127
+ reference . resolved . defs &&
128
+ reference . resolved . defs [ 0 ] &&
129
+ reference . resolved . defs [ 0 ] . name
130
+ ) ,
131
+ init : reference . init || null ,
132
+ }
133
+ }
134
+
135
+ function normalizeDef ( def ) {
136
+ return {
137
+ type : def . type ,
138
+ node : normalizeDefNode ( def . node ) ,
139
+ name : def . name . name ,
140
+ }
141
+ }
142
+
143
+ function normalizeId ( identifier ) {
144
+ return (
145
+ identifier && {
146
+ type : identifier . type ,
147
+ name : identifier . name ,
148
+ loc : identifier . loc ,
149
+ }
150
+ )
151
+ }
152
+
153
+ function normalizeDefNode ( node ) {
154
+ return {
155
+ type : node . type ,
156
+ loc : node . loc ,
157
+ }
158
+ }
159
+ }
160
+
161
+ /**
162
+ * Analyze scope
163
+ */
164
+ function analyze ( ast , parserOptions ) {
165
+ const ecmaVersion = parserOptions . ecmaVersion || 2017
166
+ const ecmaFeatures = parserOptions . ecmaFeatures || { }
167
+ const sourceType = parserOptions . sourceType || "script"
168
+ const result = escope . analyze ( ast , {
169
+ ignoreEval : true ,
170
+ nodejsScope : false ,
171
+ impliedStrict : ecmaFeatures . impliedStrict ,
172
+ ecmaVersion,
173
+ sourceType,
174
+ fallback : getFallbackKeys ,
175
+ } )
176
+
177
+ return result
178
+
179
+ function getFallbackKeys ( node ) {
180
+ return Object . keys ( node ) . filter ( fallbackKeysFilter , node )
181
+ }
182
+
183
+ function fallbackKeysFilter ( key ) {
184
+ const value = null
185
+ return (
186
+ key !== "comments" &&
187
+ key !== "leadingComments" &&
188
+ key !== "loc" &&
189
+ key !== "parent" &&
190
+ key !== "range" &&
191
+ key !== "tokens" &&
192
+ key !== "trailingComments" &&
193
+ typeof value === "object" &&
194
+ ( typeof value . type === "string" || Array . isArray ( value ) )
195
+ )
196
+ }
197
+ }
198
+
98
199
//------------------------------------------------------------------------------
99
200
// Main
100
201
//------------------------------------------------------------------------------
@@ -105,25 +206,30 @@ for (const name of TARGETS) {
105
206
const astPath = path . join ( ROOT , `${ name } /ast.json` )
106
207
const tokenRangesPath = path . join ( ROOT , `${ name } /token-ranges.json` )
107
208
const treePath = path . join ( ROOT , `${ name } /tree.json` )
209
+ const scopePath = path . join ( ROOT , `${ name } /scope.json` )
108
210
const source = fs . readFileSync ( sourcePath , "utf8" )
109
- const actual = parser . parse (
110
- source ,
111
- Object . assign (
112
- { filePath : sourcePath } ,
113
- PARSER_OPTIONS ,
114
- fs . existsSync ( optionsPath )
115
- ? JSON . parse ( fs . readFileSync ( optionsPath , "utf8" ) )
116
- : { }
117
- )
211
+ const options = Object . assign (
212
+ { filePath : sourcePath } ,
213
+ PARSER_OPTIONS ,
214
+ fs . existsSync ( optionsPath )
215
+ ? JSON . parse ( fs . readFileSync ( optionsPath , "utf8" ) )
216
+ : { }
118
217
)
119
- const tokenRanges = getAllTokens ( actual ) . map ( t =>
218
+ const actual = parser . parseForESLint ( source , options )
219
+ const tokenRanges = getAllTokens ( actual . ast ) . map ( ( t ) =>
120
220
source . slice ( t . range [ 0 ] , t . range [ 1 ] )
121
221
)
122
- const tree = getTree ( source , actual )
222
+ const tree = getTree ( source , actual . ast )
123
223
124
224
console . log ( "Update:" , name )
125
225
126
- fs . writeFileSync ( astPath , JSON . stringify ( actual , replacer , 4 ) )
226
+ fs . writeFileSync ( astPath , JSON . stringify ( actual . ast , replacer , 4 ) )
127
227
fs . writeFileSync ( tokenRangesPath , JSON . stringify ( tokenRanges , replacer , 4 ) )
128
228
fs . writeFileSync ( treePath , JSON . stringify ( tree , replacer , 4 ) )
229
+ if ( fs . existsSync ( scopePath ) ) {
230
+ fs . writeFileSync (
231
+ scopePath ,
232
+ scopeToJSON ( actual . scopeManager || analyze ( actual . ast , options ) )
233
+ )
234
+ }
129
235
}
0 commit comments