@@ -345,17 +345,7 @@ abstract class ExportDeclaration extends Stmt, @export_declaration {
345345
346346 /** Holds if this export declaration exports variable `v` under the name `name`. */
347347 overlay [ global]
348- final predicate exportsAs ( LexicalName v , string name ) {
349- this .exportsDirectlyAs ( v , name )
350- or
351- this .( ReExportDeclaration ) .reExportsAs ( v , name )
352- }
353-
354- /**
355- * Holds if this export declaration exports variable `v` under the name `name`,
356- * not counting re-exports.
357- */
358- predicate exportsDirectlyAs ( LexicalName v , string name ) { none ( ) }
348+ abstract predicate exportsAs ( LexicalName v , string name ) ;
359349
360350 /**
361351 * Gets the data flow node corresponding to the value this declaration exports
@@ -379,17 +369,7 @@ abstract class ExportDeclaration extends Stmt, @export_declaration {
379369 * to module `a` or possibly to some other module from which `a` re-exports.
380370 */
381371 overlay [ global]
382- final DataFlow:: Node getSourceNode ( string name ) {
383- result = this .getDirectSourceNode ( name )
384- or
385- result = this .( ReExportDeclaration ) .getReExportedSourceNode ( name )
386- }
387-
388- /**
389- * Gets the data flow node corresponding to the value this declaration exports
390- * under the name `name`, not including sources that come from a re-export.
391- */
392- DataFlow:: Node getDirectSourceNode ( string name ) { none ( ) }
372+ abstract DataFlow:: Node getSourceNode ( string name ) ;
393373
394374 /** Holds if is declared with the `type` keyword, so only types are exported. */
395375 predicate isTypeOnly ( ) { has_type_keyword ( this ) }
@@ -441,20 +421,20 @@ class BulkReExportDeclaration extends ReExportDeclaration, @export_all_declarati
441421 override ConstantString getImportedPath ( ) { result = this .getChildExpr ( 0 ) }
442422
443423 overlay [ global]
444- override predicate reExportsAs ( LexicalName v , string name ) {
424+ override predicate exportsAs ( LexicalName v , string name ) {
445425 this .getReExportedES2015Module ( ) .exportsAs ( v , name ) and
446- not isShadowedFromBulkExport ( this . getEnclosingModule ( ) , name )
426+ not isShadowedFromBulkExport ( this , name )
447427 }
448428
449429 overlay [ global]
450- override DataFlow:: Node getReExportedSourceNode ( string name ) {
430+ override DataFlow:: Node getSourceNode ( string name ) {
451431 result = this .getReExportedES2015Module ( ) .getAnExport ( ) .getSourceNode ( name )
452432 }
453433}
454434
455435/**
456- * Holds if bulk re-exports in `mod ` should not re-export `name` because there is an explicit export
457- * of that name in `mod` .
436+ * Holds if the given bulk export `reExport ` should not re-export `name` because there is an explicit export
437+ * of that name in the same module .
458438 *
459439 * At compile time, shadowing works across declaration spaces.
460440 * For instance, directly exporting an interface `X` will block a variable `X` from being re-exported:
@@ -466,8 +446,8 @@ class BulkReExportDeclaration extends ReExportDeclaration, @export_all_declarati
466446 * but we ignore this subtlety.
467447 */
468448overlay [ global]
469- private predicate isShadowedFromBulkExport ( Module mod , string name ) {
470- exists ( ExportNamedDeclaration other | other .getTopLevel ( ) = mod |
449+ private predicate isShadowedFromBulkExport ( BulkReExportDeclaration reExport , string name ) {
450+ exists ( ExportNamedDeclaration other | other .getTopLevel ( ) = reExport . getEnclosingModule ( ) |
471451 other .getAnExportedDecl ( ) .getName ( ) = name
472452 or
473453 other .getASpecifier ( ) .getExportedName ( ) = name
@@ -488,7 +468,8 @@ class ExportDefaultDeclaration extends ExportDeclaration, @export_default_declar
488468 /** Gets the operand statement or expression that is exported by this declaration. */
489469 ExprOrStmt getOperand ( ) { result = this .getChild ( 0 ) }
490470
491- override predicate exportsDirectlyAs ( LexicalName v , string name ) {
471+ overlay [ global]
472+ override predicate exportsAs ( LexicalName v , string name ) {
492473 name = "default" and v = this .getADecl ( ) .getVariable ( )
493474 }
494475
@@ -500,7 +481,8 @@ class ExportDefaultDeclaration extends ExportDeclaration, @export_default_declar
500481 )
501482 }
502483
503- override DataFlow:: Node getDirectSourceNode ( string name ) {
484+ overlay [ global]
485+ override DataFlow:: Node getSourceNode ( string name ) {
504486 name = "default" and result = DataFlow:: valueNode ( this .getOperand ( ) )
505487 }
506488}
@@ -542,20 +524,21 @@ class ExportNamedDeclaration extends ExportDeclaration, @export_named_declaratio
542524 /** Gets the variable declaration, if any, exported by this named export. */
543525 VarDecl getADecl ( ) { result = this .getAnExportedDecl ( ) }
544526
545- override predicate exportsDirectlyAs ( LexicalName v , string name ) {
546- (
547- exists ( LexicalDecl vd | vd = this .getAnExportedDecl ( ) |
548- name = vd .getName ( ) and v = vd .getALexicalName ( )
549- )
527+ overlay [ global]
528+ override predicate exportsAs ( LexicalName v , string name ) {
529+ exists ( LexicalDecl vd | vd = this .getAnExportedDecl ( ) |
530+ name = vd .getName ( ) and v = vd .getALexicalName ( )
531+ )
532+ or
533+ exists ( ExportSpecifier spec | spec = this .getASpecifier ( ) and name = spec .getExportedName ( ) |
534+ v = spec .getLocal ( ) .( LexicalAccess ) .getALexicalName ( )
550535 or
551- exists ( ExportSpecifier spec | spec = this .getASpecifier ( ) and name = spec .getExportedName ( ) |
552- v = spec .getLocal ( ) .( LexicalAccess ) .getALexicalName ( )
553- )
554- ) and
555- not ( this .isTypeOnly ( ) and v instanceof Variable )
536+ this .( ReExportDeclaration ) .getReExportedES2015Module ( ) .exportsAs ( v , spec .getLocalName ( ) )
537+ )
556538 }
557539
558- override DataFlow:: Node getDirectSourceNode ( string name ) {
540+ overlay [ global]
541+ override DataFlow:: Node getSourceNode ( string name ) {
559542 exists ( VarDef d | d .getTarget ( ) = this .getADecl ( ) |
560543 name = d .getTarget ( ) .( VarDecl ) .getName ( ) and
561544 result = DataFlow:: valueNode ( d .getSource ( ) )
@@ -571,11 +554,12 @@ class ExportNamedDeclaration extends ExportDeclaration, @export_named_declaratio
571554 exists ( ExportSpecifier spec | spec = this .getASpecifier ( ) and name = spec .getExportedName ( ) |
572555 not exists ( this .getImportedPath ( ) ) and result = DataFlow:: valueNode ( spec .getLocal ( ) )
573556 or
574- // For `export * as B from ".."`, we use the ExportNamespaceSpecifier as a representative for the
575- // object that gets exposed as `B`.
576- this instanceof ReExportDeclaration and
577- spec instanceof ExportNamespaceSpecifier and
578- result = DataFlow:: valueNode ( spec )
557+ exists ( ReExportDeclaration red | red = this |
558+ result = red .getReExportedES2015Module ( ) .getAnExport ( ) .getSourceNode ( spec .getLocalName ( ) )
559+ or
560+ spec instanceof ExportNamespaceSpecifier and
561+ result = DataFlow:: valueNode ( spec )
562+ )
579563 )
580564 }
581565
@@ -603,6 +587,19 @@ private class ExportNamespaceStep extends PreCallGraphStep {
603587 }
604588}
605589
590+ /**
591+ * An export declaration with the `type` modifier.
592+ */
593+ private class TypeOnlyExportDeclaration extends ExportNamedDeclaration {
594+ TypeOnlyExportDeclaration ( ) { this .isTypeOnly ( ) }
595+
596+ overlay [ global]
597+ override predicate exportsAs ( LexicalName v , string name ) {
598+ super .exportsAs ( v , name ) and
599+ not v instanceof Variable
600+ }
601+ }
602+
606603/**
607604 * An export specifier in an export declaration.
608605 *
@@ -780,20 +777,6 @@ abstract class ReExportDeclaration extends ExportDeclaration {
780777 Stages:: Imports:: ref ( ) and
781778 result .getFile ( ) = ImportPathResolver:: resolveExpr ( this .getImportedPath ( ) )
782779 }
783-
784- /**
785- * Holds if this re-export declaration ultimately re-exports `v` (from another module)
786- * under the given `name`.
787- */
788- overlay [ global]
789- abstract predicate reExportsAs ( LexicalName v , string name ) ;
790-
791- /**
792- * Gets the data flow node (from another module) corresponding to the value that is re-exported
793- * under the name `name`.
794- */
795- overlay [ global]
796- abstract DataFlow:: Node getReExportedSourceNode ( string name ) ;
797780}
798781
799782/** A literal path expression appearing in a re-export declaration. */
@@ -820,21 +803,6 @@ class SelectiveReExportDeclaration extends ReExportDeclaration, ExportNamedDecla
820803 override ConstantString getImportedPath ( ) {
821804 result = ExportNamedDeclaration .super .getImportedPath ( )
822805 }
823-
824- overlay [ global]
825- override predicate reExportsAs ( LexicalName v , string name ) {
826- exists ( ExportSpecifier spec | spec = this .getASpecifier ( ) and name = spec .getExportedName ( ) |
827- this .getReExportedES2015Module ( ) .exportsAs ( v , spec .getLocalName ( ) )
828- ) and
829- not ( this .isTypeOnly ( ) and v instanceof Variable )
830- }
831-
832- overlay [ global]
833- override DataFlow:: Node getReExportedSourceNode ( string name ) {
834- exists ( ExportSpecifier spec | spec = this .getASpecifier ( ) and name = spec .getExportedName ( ) |
835- result = this .getReExportedES2015Module ( ) .getAnExport ( ) .getSourceNode ( spec .getLocalName ( ) )
836- )
837- }
838806}
839807
840808/**
@@ -851,4 +819,16 @@ class SelectiveReExportDeclaration extends ReExportDeclaration, ExportNamedDecla
851819 */
852820class OriginalExportDeclaration extends ExportDeclaration {
853821 OriginalExportDeclaration ( ) { not this instanceof ReExportDeclaration }
822+
823+ overlay [ global]
824+ override predicate exportsAs ( LexicalName v , string name ) {
825+ this .( ExportDefaultDeclaration ) .exportsAs ( v , name ) or
826+ this .( ExportNamedDeclaration ) .exportsAs ( v , name )
827+ }
828+
829+ overlay [ global]
830+ override DataFlow:: Node getSourceNode ( string name ) {
831+ result = this .( ExportDefaultDeclaration ) .getSourceNode ( name ) or
832+ result = this .( ExportNamedDeclaration ) .getSourceNode ( name )
833+ }
854834}
0 commit comments