@@ -107,15 +107,27 @@ namespace ts {
107107
108108 // Identifiers
109109
110- export function createIdentifier ( text : string ) : Identifier {
110+ export function createIdentifier ( text : string ) : Identifier ;
111+ /* @internal */
112+ export function createIdentifier ( text : string , typeArguments : TypeNode [ ] ) : Identifier ;
113+ export function createIdentifier ( text : string , typeArguments ?: TypeNode [ ] ) : Identifier {
111114 const node = < Identifier > createSynthesizedNode ( SyntaxKind . Identifier ) ;
112115 node . text = escapeIdentifier ( text ) ;
113116 node . originalKeywordKind = text ? stringToToken ( text ) : SyntaxKind . Unknown ;
114117 node . autoGenerateKind = GeneratedIdentifierKind . None ;
115118 node . autoGenerateId = 0 ;
119+ if ( typeArguments ) {
120+ node . typeArguments = createNodeArray ( typeArguments ) ;
121+ }
116122 return node ;
117123 }
118124
125+ export function updateIdentifier ( node : Identifier , typeArguments : NodeArray < TypeNode > | undefined ) : Identifier {
126+ return node . typeArguments !== typeArguments
127+ ? updateNode ( createIdentifier ( node . text , typeArguments ) , node )
128+ : node ;
129+ }
130+
119131 let nextAutoGenerateId = 0 ;
120132
121133 /** Create a unique temporary variable. */
@@ -271,21 +283,23 @@ namespace ts {
271283
272284 // Type Elements
273285
274- export function createPropertySignature ( name : PropertyName | string , questionToken : QuestionToken | undefined , type : TypeNode | undefined , initializer : Expression | undefined ) : PropertySignature {
286+ export function createPropertySignature ( modifiers : Modifier [ ] | undefined , name : PropertyName | string , questionToken : QuestionToken | undefined , type : TypeNode | undefined , initializer : Expression | undefined ) : PropertySignature {
275287 const node = createSynthesizedNode ( SyntaxKind . PropertySignature ) as PropertySignature ;
288+ node . modifiers = asNodeArray ( modifiers ) ;
276289 node . name = asName ( name ) ;
277290 node . questionToken = questionToken ;
278291 node . type = type ;
279292 node . initializer = initializer ;
280293 return node ;
281294 }
282295
283- export function updatePropertySignature ( node : PropertySignature , name : PropertyName , questionToken : QuestionToken | undefined , type : TypeNode | undefined , initializer : Expression | undefined ) {
284- return node . name !== name
296+ export function updatePropertySignature ( node : PropertySignature , modifiers : Modifier [ ] | undefined , name : PropertyName , questionToken : QuestionToken | undefined , type : TypeNode | undefined , initializer : Expression | undefined ) {
297+ return node . modifiers !== modifiers
298+ || node . name !== name
285299 || node . questionToken !== questionToken
286300 || node . type !== type
287301 || node . initializer !== initializer
288- ? updateNode ( createPropertySignature ( name , questionToken , type , initializer ) , node )
302+ ? updateNode ( createPropertySignature ( modifiers , name , questionToken , type , initializer ) , node )
289303 : node ;
290304 }
291305
@@ -492,7 +506,7 @@ namespace ts {
492506 export function createTypeReferenceNode ( typeName : string | EntityName , typeArguments : TypeNode [ ] | undefined ) {
493507 const node = createSynthesizedNode ( SyntaxKind . TypeReference ) as TypeReferenceNode ;
494508 node . typeName = asName ( typeName ) ;
495- node . typeArguments = asNodeArray ( typeArguments ) ;
509+ node . typeArguments = typeArguments && parenthesizeTypeParameters ( typeArguments ) ;
496510 return node ;
497511 }
498512
@@ -545,7 +559,7 @@ namespace ts {
545559
546560 export function createArrayTypeNode ( elementType : TypeNode ) {
547561 const node = createSynthesizedNode ( SyntaxKind . ArrayType ) as ArrayTypeNode ;
548- node . elementType = elementType ;
562+ node . elementType = parenthesizeElementTypeMember ( elementType ) ;
549563 return node ;
550564 }
551565
@@ -585,7 +599,7 @@ namespace ts {
585599
586600 export function createUnionOrIntersectionTypeNode ( kind : SyntaxKind . UnionType | SyntaxKind . IntersectionType , types : TypeNode [ ] ) {
587601 const node = createSynthesizedNode ( kind ) as UnionTypeNode | IntersectionTypeNode ;
588- node . types = createNodeArray ( types ) ;
602+ node . types = parenthesizeElementTypeMembers ( types ) ;
589603 return node ;
590604 }
591605
@@ -614,7 +628,7 @@ namespace ts {
614628 export function createTypeOperatorNode ( type : TypeNode ) {
615629 const node = createSynthesizedNode ( SyntaxKind . TypeOperator ) as TypeOperatorNode ;
616630 node . operator = SyntaxKind . KeyOfKeyword ;
617- node . type = type ;
631+ node . type = parenthesizeElementTypeMember ( type ) ;
618632 return node ;
619633 }
620634
@@ -624,7 +638,7 @@ namespace ts {
624638
625639 export function createIndexedAccessTypeNode ( objectType : TypeNode , indexType : TypeNode ) {
626640 const node = createSynthesizedNode ( SyntaxKind . IndexedAccessType ) as IndexedAccessTypeNode ;
627- node . objectType = objectType ;
641+ node . objectType = parenthesizeElementTypeMember ( objectType ) ;
628642 node . indexType = indexType ;
629643 return node ;
630644 }
@@ -2489,6 +2503,25 @@ namespace ts {
24892503
24902504/* @internal */
24912505namespace ts {
2506+ export const nullTransformationContext : TransformationContext = {
2507+ enableEmitNotification : noop ,
2508+ enableSubstitution : noop ,
2509+ endLexicalEnvironment : ( ) => undefined ,
2510+ getCompilerOptions : notImplemented ,
2511+ getEmitHost : notImplemented ,
2512+ getEmitResolver : notImplemented ,
2513+ hoistFunctionDeclaration : noop ,
2514+ hoistVariableDeclaration : noop ,
2515+ isEmitNotificationEnabled : notImplemented ,
2516+ isSubstitutionEnabled : notImplemented ,
2517+ onEmitNode : noop ,
2518+ onSubstituteNode : notImplemented ,
2519+ readEmitHelpers : notImplemented ,
2520+ requestEmitHelper : noop ,
2521+ resumeLexicalEnvironment : noop ,
2522+ startLexicalEnvironment : noop ,
2523+ suspendLexicalEnvironment : noop
2524+ } ;
24922525
24932526 // Compound nodes
24942527
@@ -3289,16 +3322,6 @@ namespace ts {
32893322 return statements ;
32903323 }
32913324
3292- export function parenthesizeConditionalHead ( condition : Expression ) {
3293- const conditionalPrecedence = getOperatorPrecedence ( SyntaxKind . ConditionalExpression , SyntaxKind . QuestionToken ) ;
3294- const emittedCondition = skipPartiallyEmittedExpressions ( condition ) ;
3295- const conditionPrecedence = getExpressionPrecedence ( emittedCondition ) ;
3296- if ( compareValues ( conditionPrecedence , conditionalPrecedence ) === Comparison . LessThan ) {
3297- return createParen ( condition ) ;
3298- }
3299- return condition ;
3300- }
3301-
33023325 /**
33033326 * Wraps the operand to a BinaryExpression in parentheses if they are needed to preserve the intended
33043327 * order of operations.
@@ -3600,6 +3623,35 @@ namespace ts {
36003623 return expression ;
36013624 }
36023625
3626+ export function parenthesizeElementTypeMember ( member : TypeNode ) {
3627+ switch ( member . kind ) {
3628+ case SyntaxKind . UnionType :
3629+ case SyntaxKind . IntersectionType :
3630+ case SyntaxKind . FunctionType :
3631+ case SyntaxKind . ConstructorType :
3632+ return createParenthesizedType ( member ) ;
3633+ }
3634+ return member ;
3635+ }
3636+
3637+ export function parenthesizeElementTypeMembers ( members : TypeNode [ ] ) {
3638+ return createNodeArray ( sameMap ( members , parenthesizeElementTypeMember ) ) ;
3639+ }
3640+
3641+ export function parenthesizeTypeParameters ( typeParameters : TypeNode [ ] ) {
3642+ if ( some ( typeParameters ) ) {
3643+ const nodeArray = createNodeArray ( ) as NodeArray < TypeNode > ;
3644+ for ( let i = 0 ; i < typeParameters . length ; ++ i ) {
3645+ const entry = typeParameters [ i ] ;
3646+ nodeArray . push ( i === 0 && isFunctionOrConstructorTypeNode ( entry ) && entry . typeParameters ?
3647+ createParenthesizedType ( entry ) :
3648+ entry ) ;
3649+ }
3650+
3651+ return nodeArray ;
3652+ }
3653+ }
3654+
36033655 /**
36043656 * Clones a series of not-emitted expressions with a new inner expression.
36053657 *
0 commit comments