@@ -42,14 +42,14 @@ namespace ts {
42
42
context . enableSubstitution ( SyntaxKind . ShorthandPropertyAssignment ) ; // Substitutes shorthand property assignments for imported/exported symbols.
43
43
context . enableEmitNotification ( SyntaxKind . SourceFile ) ; // Restore state when substituting nodes in a file.
44
44
45
+ const zeroLiteral = factory . createNumericLiteral ( 0 ) ;
45
46
const moduleInfoMap : ExternalModuleInfo [ ] = [ ] ; // The ExternalModuleInfo for each file.
46
47
const deferredExports : ( Statement [ ] | undefined ) [ ] = [ ] ; // Exports to defer until an EndOfDeclarationMarker is found.
47
48
48
49
let currentSourceFile : SourceFile ; // The current file.
49
50
let currentModuleInfo : ExternalModuleInfo ; // The ExternalModuleInfo for the current file.
50
- let noSubstitution : boolean [ ] ; // Set of nodes for which substitution rules should be ignored.
51
+ let noSubstitution : Set < Node > ; // Set of nodes for which substitution rules should be ignored.
51
52
let needUMDDynamicImportHelper : boolean ;
52
- let bindingReferenceCache : ESMap < Node , Identifier | SourceFile | ImportClause | ImportSpecifier | undefined > | undefined ;
53
53
54
54
return chainBundle ( context , transformSourceFile ) ;
55
55
@@ -1675,7 +1675,7 @@ namespace ts {
1675
1675
if ( node . kind === SyntaxKind . SourceFile ) {
1676
1676
currentSourceFile = < SourceFile > node ;
1677
1677
currentModuleInfo = moduleInfoMap [ getOriginalNodeId ( currentSourceFile ) ] ;
1678
- noSubstitution = [ ] ;
1678
+ noSubstitution = new Set ( ) ;
1679
1679
1680
1680
previousOnEmitNode ( hint , node , emitCallback ) ;
1681
1681
@@ -1700,7 +1700,7 @@ namespace ts {
1700
1700
*/
1701
1701
function onSubstituteNode ( hint : EmitHint , node : Node ) {
1702
1702
node = previousOnSubstituteNode ( hint , node ) ;
1703
- if ( node . id && noSubstitution [ node . id ] ) {
1703
+ if ( noSubstitution . has ( node ) ) {
1704
1704
return node ;
1705
1705
}
1706
1706
@@ -1766,7 +1766,7 @@ namespace ts {
1766
1766
* - An `ImportClause` or `ImportSpecifier` if the node references an import binding.
1767
1767
* - Otherwise, `undefined`.
1768
1768
*/
1769
- function getImportOrExportBindingReferenceWorker ( node : Identifier ) : Identifier | SourceFile | ImportClause | ImportSpecifier | undefined {
1769
+ function getImportOrExportBindingReference ( node : Identifier ) : Identifier | SourceFile | ImportClause | ImportSpecifier | undefined {
1770
1770
if ( getEmitFlags ( node ) & EmitFlags . HelperName ) {
1771
1771
const externalHelpersModuleName = getExternalHelpersModuleName ( currentSourceFile ) ;
1772
1772
if ( externalHelpersModuleName ) {
@@ -1786,95 +1786,92 @@ namespace ts {
1786
1786
return undefined ;
1787
1787
}
1788
1788
1789
- /**
1790
- * For an Identifier, gets the import or export binding that it references.
1791
- * @param removeEntry When `false`, the result is cached to avoid recomputing the result in a later substitution.
1792
- * When `true`, any cached result for the node is removed.
1793
- * @returns One of the following:
1794
- * - An `Identifier` if node references an external helpers module (i.e., `tslib`).
1795
- * - A `SourceFile` if the node references an export in the file.
1796
- * - An `ImportClause` or `ImportSpecifier` if the node references an import binding.
1797
- * - Otherwise, `undefined`.
1798
- */
1799
- function getImportOrExportBindingReference ( node : Identifier , removeEntry : boolean ) : Identifier | SourceFile | ImportClause | ImportSpecifier | undefined {
1800
- let result = bindingReferenceCache ?. get ( node ) ;
1801
- if ( ! result && ! bindingReferenceCache ?. has ( node ) ) {
1802
- result = getImportOrExportBindingReferenceWorker ( node ) ;
1803
- if ( ! removeEntry ) {
1804
- bindingReferenceCache ||= new Map ( ) ;
1805
- bindingReferenceCache . set ( node , result ) ;
1806
- }
1807
- }
1808
- else if ( removeEntry ) {
1809
- bindingReferenceCache ?. delete ( node ) ;
1789
+ function substituteExpressionOfCallLike ( node : Expression ) {
1790
+ const substitute = isIdentifier ( node ) ? substituteExpressionIdentifier ( node ) : node ;
1791
+ if ( substitute !== node ) {
1792
+ return setTextRange ( factory . createParenthesizedExpression ( factory . createComma ( zeroLiteral , substitute ) ) , node ) ;
1810
1793
}
1811
- return result ;
1794
+ return node ;
1812
1795
}
1813
1796
1814
1797
function substituteCallExpression ( node : CallExpression ) {
1815
- if ( isIdentifier ( node . expression ) && getImportOrExportBindingReference ( node . expression , /*removeEntry*/ false ) ) {
1798
+ const expression = substituteExpressionOfCallLike ( node . expression ) ;
1799
+ if ( expression !== node . expression ) {
1816
1800
return isCallChain ( node ) ?
1817
1801
factory . updateCallChain ( node ,
1818
- setTextRange ( factory . createComma ( factory . createNumericLiteral ( 0 ) , node . expression ) , node . expression ) ,
1802
+ expression ,
1819
1803
node . questionDotToken ,
1820
1804
/*typeArguments*/ undefined ,
1821
1805
node . arguments ) :
1822
1806
factory . updateCallExpression ( node ,
1823
- setTextRange ( factory . createComma ( factory . createNumericLiteral ( 0 ) , node . expression ) , node . expression ) ,
1807
+ expression ,
1824
1808
/*typeArguments*/ undefined ,
1825
1809
node . arguments ) ;
1826
1810
}
1827
1811
return node ;
1828
1812
}
1829
1813
1830
1814
function substituteTaggedTemplateExpression ( node : TaggedTemplateExpression ) {
1831
- if ( isIdentifier ( node . tag ) && getImportOrExportBindingReference ( node . tag , /*removeEntry*/ false ) ) {
1815
+ const tag = substituteExpressionOfCallLike ( node . tag ) ;
1816
+ if ( tag !== node . tag ) {
1832
1817
return factory . updateTaggedTemplateExpression (
1833
1818
node ,
1834
- setTextRange ( factory . createComma ( factory . createNumericLiteral ( 0 ) , node . tag ) , node . tag ) ,
1819
+ tag ,
1835
1820
/*typeArguments*/ undefined ,
1836
1821
node . template ) ;
1837
1822
}
1838
1823
return node ;
1839
1824
}
1840
1825
1826
+
1841
1827
/**
1842
1828
* Substitution for an Identifier expression that may contain an imported or exported
1843
1829
* symbol.
1844
1830
*
1845
1831
* @param node The node to substitute.
1846
1832
*/
1847
1833
function substituteExpressionIdentifier ( node : Identifier ) : Expression {
1848
- const result = getImportOrExportBindingReference ( node , /*removeEntry*/ true ) ;
1834
+ const result = getImportOrExportBindingReference ( node ) ;
1849
1835
switch ( result ?. kind ) {
1850
1836
case SyntaxKind . Identifier : // tslib import
1837
+ noSubstitution . add ( result ) ;
1851
1838
return factory . createPropertyAccessExpression ( result , node ) ;
1852
- case SyntaxKind . SourceFile : // top-level export
1839
+ case SyntaxKind . SourceFile : { // top-level export
1840
+ const left = factory . createIdentifier ( "exports" ) ;
1841
+ noSubstitution . add ( left ) ;
1853
1842
return setTextRange (
1854
1843
factory . createPropertyAccessExpression (
1855
- factory . createIdentifier ( "exports" ) ,
1844
+ left ,
1856
1845
factory . cloneNode ( node )
1857
1846
) ,
1858
1847
/*location*/ node
1859
1848
) ;
1860
- case SyntaxKind . ImportClause :
1849
+ }
1850
+ case SyntaxKind . ImportClause : {
1851
+ const left = factory . getGeneratedNameForNode ( result . parent ) ;
1852
+ noSubstitution . add ( left ) ;
1861
1853
return setTextRange (
1862
1854
factory . createPropertyAccessExpression (
1863
- factory . getGeneratedNameForNode ( result . parent ) ,
1855
+ left ,
1864
1856
factory . createIdentifier ( "default" )
1865
1857
) ,
1866
1858
/*location*/ node
1867
1859
) ;
1868
- case SyntaxKind . ImportSpecifier :
1860
+ }
1861
+ case SyntaxKind . ImportSpecifier : {
1862
+ const left = factory . getGeneratedNameForNode ( result . parent ?. parent ?. parent || result ) ;
1863
+ noSubstitution . add ( left ) ;
1869
1864
const name = result . propertyName || result . name ;
1870
1865
return setTextRange (
1871
1866
factory . createPropertyAccessExpression (
1872
- factory . getGeneratedNameForNode ( result . parent ?. parent ?. parent || result ) ,
1867
+ left ,
1873
1868
factory . cloneNode ( name )
1874
1869
) ,
1875
1870
/*location*/ node
1876
1871
) ;
1872
+ }
1877
1873
default :
1874
+ noSubstitution . add ( node ) ;
1878
1875
return node ;
1879
1876
}
1880
1877
}
@@ -1904,7 +1901,7 @@ namespace ts {
1904
1901
let expression : Expression = node ;
1905
1902
for ( const exportName of exportedNames ) {
1906
1903
// Mark the node to prevent triggering this rule again.
1907
- noSubstitution [ getNodeId ( expression ) ] = true ;
1904
+ noSubstitution . add ( expression ) ;
1908
1905
expression = createExportExpression ( exportName , expression , /*location*/ node ) ;
1909
1906
}
1910
1907
@@ -1947,11 +1944,11 @@ namespace ts {
1947
1944
: node ;
1948
1945
for ( const exportName of exportedNames ) {
1949
1946
// Mark the node to prevent triggering this rule again.
1950
- noSubstitution [ getNodeId ( expression ) ] = true ;
1947
+ noSubstitution . add ( expression ) ;
1951
1948
expression = createExportExpression ( exportName , expression ) ;
1952
1949
}
1953
1950
if ( node . kind === SyntaxKind . PostfixUnaryExpression ) {
1954
- noSubstitution [ getNodeId ( expression ) ] = true ;
1951
+ noSubstitution . add ( expression ) ;
1955
1952
expression = node . operator === SyntaxKind . PlusPlusToken
1956
1953
? factory . createSubtract ( expression , factory . createNumericLiteral ( 1 ) )
1957
1954
: factory . createAdd ( expression , factory . createNumericLiteral ( 1 ) ) ;
0 commit comments