@@ -909,6 +909,9 @@ namespace ts {
909909 let currentParenthesizerRule : ( ( node : Node ) => Node ) | undefined ;
910910 const { enter : enterComment , exit : exitComment } = performance . createTimerIf ( extendedDiagnostics , "commentTime" , "beforeComment" , "afterComment" ) ;
911911 const parenthesizer = factory . parenthesizer ;
912+ const typeArgumentParenthesizerRuleSelector : OrdinalParentheizerRuleSelector < Node > = {
913+ select : index => index === 0 ? parenthesizer . parenthesizeLeadingTypeArgument : undefined
914+ } ;
912915 const emitBinaryExpression = createEmitBinaryExpression ( ) ;
913916
914917 reset ( ) ;
@@ -2241,7 +2244,7 @@ namespace ts {
22412244 }
22422245
22432246 function emitArrayType ( node : ArrayTypeNode ) {
2244- emit ( node . elementType , parenthesizer . parenthesizeElementTypeOfArrayType ) ;
2247+ emit ( node . elementType , parenthesizer . parenthesizeNonArrayTypeOfPostfixType ) ;
22452248 writePunctuation ( "[" ) ;
22462249 writePunctuation ( "]" ) ;
22472250 }
@@ -2254,7 +2257,7 @@ namespace ts {
22542257 function emitTupleType ( node : TupleTypeNode ) {
22552258 emitTokenWithComment ( SyntaxKind . OpenBracketToken , node . pos , writePunctuation , node ) ;
22562259 const flags = getEmitFlags ( node ) & EmitFlags . SingleLine ? ListFormat . SingleLineTupleTypeElements : ListFormat . MultiLineTupleTypeElements ;
2257- emitList ( node , node . elements , flags | ListFormat . NoSpaceIfEmpty ) ;
2260+ emitList ( node , node . elements , flags | ListFormat . NoSpaceIfEmpty , parenthesizer . parenthesizeElementTypeOfTupleType ) ;
22582261 emitTokenWithComment ( SyntaxKind . CloseBracketToken , node . elements . end , writePunctuation , node ) ;
22592262 }
22602263
@@ -2268,24 +2271,24 @@ namespace ts {
22682271 }
22692272
22702273 function emitOptionalType ( node : OptionalTypeNode ) {
2271- emit ( node . type , parenthesizer . parenthesizeElementTypeOfArrayType ) ;
2274+ emit ( node . type , parenthesizer . parenthesizeTypeOfOptionalType ) ;
22722275 writePunctuation ( "?" ) ;
22732276 }
22742277
22752278 function emitUnionType ( node : UnionTypeNode ) {
2276- emitList ( node , node . types , ListFormat . UnionTypeConstituents , parenthesizer . parenthesizeMemberOfElementType ) ;
2279+ emitList ( node , node . types , ListFormat . UnionTypeConstituents , parenthesizer . parenthesizeConstituentTypeOfUnionType ) ;
22772280 }
22782281
22792282 function emitIntersectionType ( node : IntersectionTypeNode ) {
2280- emitList ( node , node . types , ListFormat . IntersectionTypeConstituents , parenthesizer . parenthesizeMemberOfElementType ) ;
2283+ emitList ( node , node . types , ListFormat . IntersectionTypeConstituents , parenthesizer . parenthesizeConstituentTypeOfIntersectionType ) ;
22812284 }
22822285
22832286 function emitConditionalType ( node : ConditionalTypeNode ) {
2284- emit ( node . checkType , parenthesizer . parenthesizeMemberOfConditionalType ) ;
2287+ emit ( node . checkType , parenthesizer . parenthesizeCheckTypeOfConditionalType ) ;
22852288 writeSpace ( ) ;
22862289 writeKeyword ( "extends" ) ;
22872290 writeSpace ( ) ;
2288- emit ( node . extendsType , parenthesizer . parenthesizeMemberOfConditionalType ) ;
2291+ emit ( node . extendsType , parenthesizer . parenthesizeExtendsTypeOfConditionalType ) ;
22892292 writeSpace ( ) ;
22902293 writePunctuation ( "?" ) ;
22912294 writeSpace ( ) ;
@@ -2315,11 +2318,15 @@ namespace ts {
23152318 function emitTypeOperator ( node : TypeOperatorNode ) {
23162319 writeTokenText ( node . operator , writeKeyword ) ;
23172320 writeSpace ( ) ;
2318- emit ( node . type , parenthesizer . parenthesizeMemberOfElementType ) ;
2321+
2322+ const parenthesizerRule = node . operator === SyntaxKind . ReadonlyKeyword ?
2323+ parenthesizer . parenthesizeOperandOfReadonlyTypeOperator :
2324+ parenthesizer . parenthesizeOperandOfTypeOperator ;
2325+ emit ( node . type , parenthesizerRule ) ;
23192326 }
23202327
23212328 function emitIndexedAccessType ( node : IndexedAccessTypeNode ) {
2322- emit ( node . objectType , parenthesizer . parenthesizeMemberOfElementType ) ;
2329+ emit ( node . objectType , parenthesizer . parenthesizeNonArrayTypeOfPostfixType ) ;
23232330 writePunctuation ( "[" ) ;
23242331 emit ( node . indexType ) ;
23252332 writePunctuation ( "]" ) ;
@@ -4256,7 +4263,7 @@ namespace ts {
42564263 }
42574264
42584265 function emitTypeArguments ( parentNode : Node , typeArguments : NodeArray < TypeNode > | undefined ) {
4259- emitList ( parentNode , typeArguments , ListFormat . TypeArguments , parenthesizer . parenthesizeMemberOfElementType ) ;
4266+ emitList ( parentNode , typeArguments , ListFormat . TypeArguments , typeArgumentParenthesizerRuleSelector ) ;
42604267 }
42614268
42624269 function emitTypeParameters ( parentNode : SignatureDeclaration | InterfaceDeclaration | TypeAliasDeclaration | ClassDeclaration | ClassExpression , typeParameters : NodeArray < TypeParameterDeclaration > | undefined ) {
@@ -4324,15 +4331,15 @@ namespace ts {
43244331 }
43254332 }
43264333
4327- function emitList ( parentNode : Node | undefined , children : NodeArray < Node > | undefined , format : ListFormat , parenthesizerRule ?: ( node : Node ) => Node , start ?: number , count ?: number ) {
4334+ function emitList ( parentNode : Node | undefined , children : NodeArray < Node > | undefined , format : ListFormat , parenthesizerRule ?: ParenthesizerRuleOrSelector < Node > , start ?: number , count ?: number ) {
43284335 emitNodeList ( emit , parentNode , children , format , parenthesizerRule , start , count ) ;
43294336 }
43304337
4331- function emitExpressionList ( parentNode : Node | undefined , children : NodeArray < Node > | undefined , format : ListFormat , parenthesizerRule ?: ( node : Expression ) => Expression , start ?: number , count ?: number ) {
4338+ function emitExpressionList ( parentNode : Node | undefined , children : NodeArray < Node > | undefined , format : ListFormat , parenthesizerRule ?: ParenthesizerRuleOrSelector < Expression > , start ?: number , count ?: number ) {
43324339 emitNodeList ( emitExpression , parentNode , children , format , parenthesizerRule , start , count ) ;
43334340 }
43344341
4335- function emitNodeList ( emit : ( node : Node , parenthesizerRule ?: ( ( node : Node ) => Node ) | undefined ) => void , parentNode : Node | undefined , children : NodeArray < Node > | undefined , format : ListFormat , parenthesizerRule : ( ( node : Node ) => Node ) | undefined , start = 0 , count = children ? children . length - start : 0 ) {
4342+ function emitNodeList ( emit : ( node : Node , parenthesizerRule ?: ( ( node : Node ) => Node ) | undefined ) => void , parentNode : Node | undefined , children : NodeArray < Node > | undefined , format : ListFormat , parenthesizerRule : ParenthesizerRuleOrSelector < Node > | undefined , start = 0 , count = children ? children . length - start : 0 ) {
43364343 const isUndefined = children === undefined ;
43374344 if ( isUndefined && format & ListFormat . OptionalIfUndefined ) {
43384345 return ;
@@ -4388,6 +4395,8 @@ namespace ts {
43884395 increaseIndent ( ) ;
43894396 }
43904397
4398+ const emitListItem = getEmitListItem ( emit , parenthesizerRule ) ;
4399+
43914400 // Emit each child.
43924401 let previousSibling : Node | undefined ;
43934402 let previousSourceFileTextKind : ReturnType < typeof recordBundleFileInternalSectionStart > ;
@@ -4443,12 +4452,7 @@ namespace ts {
44434452 }
44444453
44454454 nextListElementPos = child . pos ;
4446- if ( emit . length === 1 ) {
4447- emit ( child ) ;
4448- }
4449- else {
4450- emit ( child , parenthesizerRule ) ;
4451- }
4455+ emitListItem ( child , emit , parenthesizerRule , i ) ;
44524456
44534457 if ( shouldDecreaseIndentAfterEmit ) {
44544458 decreaseIndent ( ) ;
@@ -5890,4 +5894,30 @@ namespace ts {
58905894 CountMask = 0x0FFFFFFF , // Temp variable counter
58915895 _i = 0x10000000 , // Use/preference flag for '_i'
58925896 }
5897+
5898+ interface OrdinalParentheizerRuleSelector < T extends Node > {
5899+ select ( index : number ) : ( ( node : T ) => T ) | undefined ;
5900+ }
5901+
5902+ type ParenthesizerRule < T extends Node > = ( node : T ) => T ;
5903+
5904+ type ParenthesizerRuleOrSelector < T extends Node > = OrdinalParentheizerRuleSelector < T > | ParenthesizerRule < T > ;
5905+
5906+ function emitListItemNoParenthesizer ( node : Node , emit : ( node : Node , parenthesizerRule ?: ( ( node : Node ) => Node ) | undefined ) => void , _parenthesizerRule : ParenthesizerRuleOrSelector < Node > | undefined , _index : number ) {
5907+ emit ( node ) ;
5908+ }
5909+
5910+ function emitListItemWithParenthesizerRuleSelector ( node : Node , emit : ( node : Node , parenthesizerRule ?: ( ( node : Node ) => Node ) | undefined ) => void , parenthesizerRuleSelector : OrdinalParentheizerRuleSelector < Node > , index : number ) {
5911+ emit ( node , parenthesizerRuleSelector . select ( index ) ) ;
5912+ }
5913+
5914+ function emitListItemWithParenthesizerRule ( node : Node , emit : ( node : Node , parenthesizerRule ?: ( ( node : Node ) => Node ) | undefined ) => void , parenthesizerRule : ParenthesizerRule < Node > | undefined , _index : number ) {
5915+ emit ( node , parenthesizerRule ) ;
5916+ }
5917+
5918+ function getEmitListItem < T extends Node , R extends ParenthesizerRuleOrSelector < T > | undefined > ( emit : ( node : Node , parenthesizerRule ?: ( ( node : Node ) => Node ) | undefined ) => void , parenthesizerRule : R ) : ( node : Node , emit : ( node : Node , parenthesizerRule ?: ( ( node : Node ) => Node ) | undefined ) => void , parenthesizerRule : R , index : number ) => void {
5919+ return emit . length === 1 ? emitListItemNoParenthesizer :
5920+ typeof parenthesizerRule === "object" ? emitListItemWithParenthesizerRuleSelector :
5921+ emitListItemWithParenthesizerRule ;
5922+ }
58935923}
0 commit comments