@@ -213,26 +213,40 @@ export function createCustomBlockSharedContext({
213213 parserOptions : any
214214} ) {
215215 let sourceCode : SourceCode
216- let scopeManager : ScopeManager
217216 let currentNode : any
218217 return {
219218 serCurrentNode ( node : any ) {
220219 currentNode = node
221220 } ,
222221 context : {
223- getAncestors : ( ) => getAncestors ( currentNode ) ,
224-
222+ getAncestors : ( ) => getSourceCode ( ) . getAncestors ( currentNode ) ,
225223 getDeclaredVariables : ( ...args : any [ ] ) =>
226224 // @ts -expect-error -- ignore
227- getScopeManager ( ) . getDeclaredVariables ( ...args ) ,
228- getScope : ( ) => getScope ( getScopeManager ( ) , currentNode ) ,
225+ getSourceCode ( ) . getDeclaredVariables ( ...args ) ,
226+ getScope : ( ) => getSourceCode ( ) . getScope ( currentNode ) ,
229227 markVariableAsUsed : ( name : string ) =>
230- markVariableAsUsed (
231- getScopeManager ( ) ,
232- currentNode ,
233- parserOptions ,
234- name ,
235- ) ,
228+ getSourceCode ( ) . markVariableAsUsed ( name , currentNode ) ,
229+ get parserServices ( ) {
230+ return getSourceCode ( ) . parserServices
231+ } ,
232+ getSourceCode,
233+ get sourceCode ( ) {
234+ return getSourceCode ( )
235+ } ,
236+ } ,
237+ }
238+
239+ function getSourceCode ( ) : SourceCode {
240+ if ( sourceCode ) {
241+ return sourceCode
242+ }
243+
244+ const scopeManager = getScopeManager ( )
245+
246+ // eslint-disable-next-line @typescript-eslint/no-require-imports
247+ const originalSourceCode = new ( require ( "eslint" ) . SourceCode ) ( {
248+ text,
249+ ast : parsedResult . ast ,
236250 parserServices : {
237251 customBlock,
238252 parseCustomBlockElement (
@@ -251,44 +265,43 @@ export function createCustomBlockSharedContext({
251265 ? { parseError : parsedResult . error }
252266 : { } ) ,
253267 } ,
254- getSourceCode,
255- get sourceCode ( ) {
256- return getSourceCode ( )
257- } ,
258- } ,
259- }
268+ scopeManager,
269+ visitorKeys : parsedResult . visitorKeys ,
270+ } )
260271
261- function getSourceCode ( ) {
262- return (
263- sourceCode ||
264- // eslint-disable-next-line @typescript-eslint/no-require-imports
265- ( sourceCode = new ( require ( "eslint" ) . SourceCode ) ( {
266- text,
267- ast : parsedResult . ast ,
268- parserServices : parsedResult . services ,
269- scopeManager : getScopeManager ( ) ,
270- visitorKeys : parsedResult . visitorKeys ,
271- } ) )
272- )
272+ const polyfills = {
273+ markVariableAsUsed : ( name : string , node : any ) =>
274+ markVariableAsUsed ( scopeManager , node , parsedResult . ast , name ) ,
275+ getScope : ( node : any ) => getScope ( scopeManager , node ) ,
276+ getAncestors : ( node : any ) => getAncestors ( node ) ,
277+ getDeclaredVariables : ( ...args : any [ ] ) =>
278+ // @ts -expect-error -- ignore
279+ scopeManager . getDeclaredVariables ( ...args ) ,
280+ }
281+
282+ return ( sourceCode = new Proxy ( originalSourceCode , {
283+ get ( _target , prop ) {
284+ return originalSourceCode [ prop ] || ( polyfills as any ) [ prop ]
285+ } ,
286+ } ) )
273287 }
274288
275289 function getScopeManager ( ) {
276- if ( parsedResult . scopeManager || scopeManager ) {
277- return parsedResult . scopeManager || scopeManager
290+ if ( parsedResult . scopeManager ) {
291+ return parsedResult . scopeManager
278292 }
279293
280294 const ecmaVersion = getEcmaVersionIfUseEspree ( parserOptions ) || 2022
281295 const ecmaFeatures = parserOptions . ecmaFeatures || { }
282296 const sourceType = parserOptions . sourceType || "script"
283- scopeManager = getEslintScope ( ) . analyze ( parsedResult . ast , {
297+ return getEslintScope ( ) . analyze ( parsedResult . ast , {
284298 ignoreEval : true ,
285299 nodejsScope : false ,
286300 impliedStrict : ecmaFeatures . impliedStrict ,
287301 ecmaVersion,
288302 sourceType,
289303 fallback : getFallbackKeys ,
290304 } )
291- return scopeManager
292305 }
293306}
294307
@@ -349,20 +362,19 @@ function getScope(scopeManager: ScopeManager, currentNode: Node) {
349362function markVariableAsUsed (
350363 scopeManager : ScopeManager ,
351364 currentNode : Node ,
352- parserOptions : any ,
365+ program : Node ,
353366 name : string ,
354367) {
355- const hasGlobalReturn =
356- parserOptions . ecmaFeatures && parserOptions . ecmaFeatures . globalReturn
357- const specialScope =
358- hasGlobalReturn || parserOptions . sourceType === "module"
359368 const currentScope = getScope ( scopeManager , currentNode )
360-
361- // Special Node.js scope means we need to start one level deeper
362- const initialScope =
363- currentScope . type === "global" && specialScope
364- ? currentScope . childScopes [ 0 ]
365- : currentScope
369+ let initialScope = currentScope
370+ if (
371+ currentScope . type === "global" &&
372+ currentScope . childScopes . length > 0 &&
373+ // top-level scopes refer to a `Program` node
374+ currentScope . childScopes [ 0 ] . block === program
375+ ) {
376+ initialScope = currentScope . childScopes [ 0 ]
377+ }
366378
367379 for ( let scope : Scope | null = initialScope ; scope ; scope = scope . upper ) {
368380 const variable = scope . variables . find (
0 commit comments