@@ -1580,20 +1580,60 @@ namespace ts {
1580
1580
return isFunctionLike ( n ) || n . kind === SyntaxKind . ModuleDeclaration || n . kind === SyntaxKind . SourceFile ;
1581
1581
}
1582
1582
1583
- export function cloneEntityName ( node : EntityName ) : EntityName {
1584
- if ( node . kind === SyntaxKind . Identifier ) {
1585
- const clone = < Identifier > createSynthesizedNode ( SyntaxKind . Identifier ) ;
1586
- clone . text = ( < Identifier > node ) . text ;
1587
- return clone ;
1583
+ /**
1584
+ * Creates a shallow, memberwise clone of a node. The "kind", "pos", "end", "flags", and "parent"
1585
+ * properties are excluded by default, and can be provided via the "location", "flags", and
1586
+ * "parent" parameters.
1587
+ * @param node The node to clone.
1588
+ * @param location An optional TextRange to use to supply the new position.
1589
+ * @param flags The NodeFlags to use for the cloned node.
1590
+ * @param parent The parent for the new node.
1591
+ */
1592
+ export function cloneNode < T extends Node > ( node : T , location ?: TextRange , flags ?: NodeFlags , parent ?: Node ) : T {
1593
+ // We don't use "clone" from core.ts here, as we need to preserve the prototype chain of
1594
+ // the original node. We also need to exclude specific properties and only include own-
1595
+ // properties (to skip members already defined on the shared prototype).
1596
+ const clone = location !== undefined
1597
+ ? < T > createNode ( node . kind , location . pos , location . end )
1598
+ : < T > createSynthesizedNode ( node . kind ) ;
1599
+
1600
+ for ( const key in node ) {
1601
+ if ( clone . hasOwnProperty ( key ) || ! node . hasOwnProperty ( key ) ) {
1602
+ continue ;
1603
+ }
1604
+
1605
+ ( < any > clone ) [ key ] = ( < any > node ) [ key ] ;
1588
1606
}
1589
- else {
1590
- const clone = < QualifiedName > createSynthesizedNode ( SyntaxKind . QualifiedName ) ;
1591
- clone . left = cloneEntityName ( ( < QualifiedName > node ) . left ) ;
1592
- clone . left . parent = clone ;
1593
- clone . right = < Identifier > cloneEntityName ( ( < QualifiedName > node ) . right ) ;
1594
- clone . right . parent = clone ;
1595
- return clone ;
1607
+
1608
+ if ( flags !== undefined ) {
1609
+ clone . flags = flags ;
1610
+ }
1611
+
1612
+ if ( parent !== undefined ) {
1613
+ clone . parent = parent ;
1596
1614
}
1615
+
1616
+ return clone ;
1617
+ }
1618
+
1619
+ /**
1620
+ * Creates a deep clone of an EntityName, with new parent pointers.
1621
+ * @param node The EntityName to clone.
1622
+ * @param parent The parent for the cloned node.
1623
+ */
1624
+ export function cloneEntityName ( node : EntityName , parent ?: Node ) : EntityName {
1625
+ const clone = cloneNode ( node , node , node . flags , parent ) ;
1626
+ if ( isQualifiedName ( clone ) ) {
1627
+ const { left, right } = clone ;
1628
+ clone . left = cloneEntityName ( left , clone ) ;
1629
+ clone . right = cloneNode ( right , right , right . flags , parent ) ;
1630
+ }
1631
+
1632
+ return clone ;
1633
+ }
1634
+
1635
+ export function isQualifiedName ( node : Node ) : node is QualifiedName {
1636
+ return node . kind === SyntaxKind . QualifiedName ;
1597
1637
}
1598
1638
1599
1639
export function nodeIsSynthesized ( node : Node ) : boolean {
@@ -1936,7 +1976,7 @@ namespace ts {
1936
1976
const bundledSources = filter ( host . getSourceFiles ( ) ,
1937
1977
sourceFile => ! isDeclarationFile ( sourceFile ) && // Not a declaration file
1938
1978
( ! isExternalModule ( sourceFile ) || // non module file
1939
- ( getEmitModuleKind ( options ) && isExternalModule ( sourceFile ) ) ) ) ; // module that can emit - note falsy value from getEmitModuleKind means the module kind that shouldn't be emitted
1979
+ ( getEmitModuleKind ( options ) && isExternalModule ( sourceFile ) ) ) ) ; // module that can emit - note falsy value from getEmitModuleKind means the module kind that shouldn't be emitted
1940
1980
if ( bundledSources . length ) {
1941
1981
const jsFilePath = options . outFile || options . out ;
1942
1982
const emitFileNames : EmitFileNames = {
0 commit comments