@@ -7,7 +7,7 @@ import { JSUtils, ExtendedPluginBuilder } from './js-utils';
7
7
import type { EmberTemplateCompiler , PreprocessOptions } from './ember-template-compiler' ;
8
8
import { LegacyModuleName } from './public-types' ;
9
9
import { ScopeLocals } from './scope-locals' ;
10
- import { ASTPluginBuilder , getTemplateLocals , preprocess , print } from '@glimmer/syntax' ;
10
+ import { ASTPluginBuilder , preprocess , print , traverse , WalkerPath } from '@glimmer/syntax' ;
11
11
12
12
export * from './public-types' ;
13
13
@@ -373,31 +373,57 @@ function runtimeErrorIIFE(babel: typeof Babel, replacements: { ERROR_MESSAGE: st
373
373
function buildScopeLocals (
374
374
userTypedOptions : Record < string , unknown > ,
375
375
formatOptions : ModuleConfig ,
376
- templateContent : string
376
+ templateContent : string ,
377
+ path : NodePath < t . Expression >
377
378
) : ScopeLocals {
378
379
if ( formatOptions . rfc931Support && userTypedOptions . eval ) {
379
- return discoverLocals ( templateContent ) ;
380
+ return discoverLocals ( templateContent , path ) ;
380
381
} else if ( userTypedOptions . scope ) {
381
382
return userTypedOptions . scope as ScopeLocals ;
382
383
} else {
383
384
return new ScopeLocals ( ) ;
384
385
}
385
386
}
386
387
387
- function discoverLocals ( templateContent : string ) : ScopeLocals {
388
- // this is wrong, but the right thing is unreleased in
389
- // https://github.com/glimmerjs/glimmer-vm/pull/1421, so for the moment I'm
390
- // sticking with the exact behavior that ember-templates-imports has.
391
- //
392
- // (the reason it's wrong is that the correct answer depends on not just the
393
- // template, but the ambient javascript scope. Anything in locals needs to win
394
- // over ember keywords. Otherwise we can never introduce new keywords.)
388
+ function discoverLocals ( templateContent : string , jsPath : NodePath < t . Expression > ) : ScopeLocals {
395
389
let scopeLocals = new ScopeLocals ( ) ;
396
- for ( let local of getTemplateLocals ( templateContent ) ) {
397
- if ( local . match ( / ^ [ $ A - Z _ ] [ 0 - 9 A - Z _ $ ] * $ / i) ) {
398
- scopeLocals . add ( local ) ;
390
+ const ast = preprocess ( templateContent ) ;
391
+ function isInScope ( path : WalkerPath < any > , name : string ) {
392
+ while ( path . parent ) {
393
+ path = path . parent ;
394
+ if ( path . node . blockParams && path . node . blockParams . includes ( name ) ) {
395
+ return true ;
396
+ }
397
+ }
398
+ return false ;
399
+ }
400
+
401
+ function isInJsScope ( name : string ) {
402
+ if ( jsPath . scope . getBinding ( name ) ) return true ;
403
+ if ( [ 'this' , 'globalThis' ] . includes ( name ) ) return true ;
404
+ if ( jsPath . state . originalImportedNames . has ( name ) ) {
405
+ return true ;
399
406
}
407
+ return false ;
400
408
}
409
+
410
+ traverse ( ast , {
411
+ PathExpression ( node , path ) {
412
+ if (
413
+ node . head . type === 'VarHead' &&
414
+ ! isInScope ( path , node . head . name ) &&
415
+ isInJsScope ( node . head . name )
416
+ ) {
417
+ scopeLocals . add ( node . head . name ) ;
418
+ }
419
+ } ,
420
+ ElementNode ( node , path ) {
421
+ const name = node . tag . split ( '.' ) [ 0 ] ;
422
+ if ( ! isInScope ( path , name ) && isInJsScope ( name ) ) {
423
+ scopeLocals . add ( name ) ;
424
+ }
425
+ } ,
426
+ } ) ;
401
427
return scopeLocals ;
402
428
}
403
429
@@ -483,7 +509,8 @@ function insertCompiledTemplate<EnvSpecificOptions>(
483
509
backingClass : NodePath < Parameters < typeof t . callExpression > [ 1 ] [ number ] > | undefined
484
510
) {
485
511
let t = babel . types ;
486
- let scopeLocals = buildScopeLocals ( userTypedOptions , config , template ) ;
512
+ target . state = state ;
513
+ let scopeLocals = buildScopeLocals ( userTypedOptions , config , template , target ) ;
487
514
let options = buildPrecompileOptions (
488
515
babel ,
489
516
target ,
@@ -560,7 +587,8 @@ function insertTransformedTemplate<EnvSpecificOptions>(
560
587
backingClass : NodePath < Parameters < typeof t . callExpression > [ 1 ] [ number ] > | undefined
561
588
) {
562
589
let t = babel . types ;
563
- let scopeLocals = buildScopeLocals ( userTypedOptions , formatOptions , template ) ;
590
+ target . state = state ;
591
+ let scopeLocals = buildScopeLocals ( userTypedOptions , formatOptions , template , target ) ;
564
592
let options = buildPrecompileOptions (
565
593
babel ,
566
594
target ,
0 commit comments