@@ -28,7 +28,7 @@ module NameResolution {
2828 Location getLocation ( ) {
2929 result = this .( AstNode ) .getLocation ( )
3030 or
31- result = this .( LocalVariable ) .getLocation ( )
31+ result = this .( LocalVariableLike ) .getLocation ( )
3232 or
3333 result = this .( JSDocTypeExpr ) .getLocation ( )
3434 }
@@ -47,6 +47,22 @@ module NameResolution {
4747 }
4848 }
4949
50+ /**
51+ * A local variable, or a top-level variable that acts as a global variable due to an ambient declaration.
52+ */
53+ class LocalVariableLike extends Variable {
54+ LocalVariableLike ( ) { this .isLocal ( ) or this .isTopLevelWithAmbientDeclaration ( ) }
55+
56+ Location getLocation ( ) {
57+ result =
58+ min ( Location loc |
59+ loc = this .getADeclaration ( ) .getLocation ( )
60+ |
61+ loc order by loc .getStartLine ( ) , loc .getStartColumn ( )
62+ )
63+ }
64+ }
65+
5066 /**
5167 * Holds if values/namespaces/types in `node1` can flow to values/namespaces/types in `node2`.
5268 */
@@ -224,7 +240,7 @@ module NameResolution {
224240 /**
225241 * A local variable with exactly one definition, not counting implicit initialization.
226242 */
227- private class EffectivelyConstantVariable extends LocalVariable {
243+ private class EffectivelyConstantVariable extends LocalVariableLike {
228244 EffectivelyConstantVariable ( ) {
229245 count ( SsaExplicitDefinition ssa | ssa .getSourceVariable ( ) = this ) <= 1 // count may be zero if ambient
230246 }
@@ -294,7 +310,7 @@ module NameResolution {
294310 * Holds if `value` is stored in `target.prop`. Only needs to recognise assignments
295311 * that are also recognised by JSDoc tooling such as the Closure compiler.
296312 */
297- private predicate storeToVariable ( Expr value , string prop , LocalVariable target ) {
313+ private predicate storeToVariable ( Expr value , string prop , LocalVariableLike target ) {
298314 exists ( AssignExpr assign |
299315 // exports.name = value
300316 assign .getLhs ( ) .( PropAccess ) .accesses ( target .getAnAccess ( ) , prop ) and
0 commit comments