@@ -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 ( ) ;
@@ -2240,7 +2243,7 @@ namespace ts {
22402243 }
22412244
22422245 function emitArrayType ( node : ArrayTypeNode ) {
2243- emit ( node . elementType , parenthesizer . parenthesizeElementTypeOfArrayType ) ;
2246+ emit ( node . elementType , parenthesizer . parenthesizeNonArrayTypeOfPostfixType ) ;
22442247 writePunctuation ( "[" ) ;
22452248 writePunctuation ( "]" ) ;
22462249 }
@@ -2253,7 +2256,7 @@ namespace ts {
22532256 function emitTupleType ( node : TupleTypeNode ) {
22542257 emitTokenWithComment ( SyntaxKind . OpenBracketToken , node . pos , writePunctuation , node ) ;
22552258 const flags = getEmitFlags ( node ) & EmitFlags . SingleLine ? ListFormat . SingleLineTupleTypeElements : ListFormat . MultiLineTupleTypeElements ;
2256- emitList ( node , node . elements , flags | ListFormat . NoSpaceIfEmpty ) ;
2259+ emitList ( node , node . elements , flags | ListFormat . NoSpaceIfEmpty , parenthesizer . parenthesizeElementTypeOfTupleType ) ;
22572260 emitTokenWithComment ( SyntaxKind . CloseBracketToken , node . elements . end , writePunctuation , node ) ;
22582261 }
22592262
@@ -2267,24 +2270,24 @@ namespace ts {
22672270 }
22682271
22692272 function emitOptionalType ( node : OptionalTypeNode ) {
2270- emit ( node . type , parenthesizer . parenthesizeElementTypeOfArrayType ) ;
2273+ emit ( node . type , parenthesizer . parenthesizeTypeOfOptionalType ) ;
22712274 writePunctuation ( "?" ) ;
22722275 }
22732276
22742277 function emitUnionType ( node : UnionTypeNode ) {
2275- emitList ( node , node . types , ListFormat . UnionTypeConstituents , parenthesizer . parenthesizeMemberOfElementType ) ;
2278+ emitList ( node , node . types , ListFormat . UnionTypeConstituents , parenthesizer . parenthesizeConstituentTypeOfUnionType ) ;
22762279 }
22772280
22782281 function emitIntersectionType ( node : IntersectionTypeNode ) {
2279- emitList ( node , node . types , ListFormat . IntersectionTypeConstituents , parenthesizer . parenthesizeMemberOfElementType ) ;
2282+ emitList ( node , node . types , ListFormat . IntersectionTypeConstituents , parenthesizer . parenthesizeConstituentTypeOfIntersectionType ) ;
22802283 }
22812284
22822285 function emitConditionalType ( node : ConditionalTypeNode ) {
2283- emit ( node . checkType , parenthesizer . parenthesizeMemberOfConditionalType ) ;
2286+ emit ( node . checkType , parenthesizer . parenthesizeCheckTypeOfConditionalType ) ;
22842287 writeSpace ( ) ;
22852288 writeKeyword ( "extends" ) ;
22862289 writeSpace ( ) ;
2287- emit ( node . extendsType , parenthesizer . parenthesizeMemberOfConditionalType ) ;
2290+ emit ( node . extendsType , parenthesizer . parenthesizeExtendsTypeOfConditionalType ) ;
22882291 writeSpace ( ) ;
22892292 writePunctuation ( "?" ) ;
22902293 writeSpace ( ) ;
@@ -2314,11 +2317,15 @@ namespace ts {
23142317 function emitTypeOperator ( node : TypeOperatorNode ) {
23152318 writeTokenText ( node . operator , writeKeyword ) ;
23162319 writeSpace ( ) ;
2317- emit ( node . type , parenthesizer . parenthesizeMemberOfElementType ) ;
2320+
2321+ const parenthesizerRule = node . operator === SyntaxKind . ReadonlyKeyword ?
2322+ parenthesizer . parenthesizeOperandOfReadonlyTypeOperator :
2323+ parenthesizer . parenthesizeOperandOfTypeOperator ;
2324+ emit ( node . type , parenthesizerRule ) ;
23182325 }
23192326
23202327 function emitIndexedAccessType ( node : IndexedAccessTypeNode ) {
2321- emit ( node . objectType , parenthesizer . parenthesizeMemberOfElementType ) ;
2328+ emit ( node . objectType , parenthesizer . parenthesizeNonArrayTypeOfPostfixType ) ;
23222329 writePunctuation ( "[" ) ;
23232330 emit ( node . indexType ) ;
23242331 writePunctuation ( "]" ) ;
@@ -4254,7 +4261,7 @@ namespace ts {
42544261 }
42554262
42564263 function emitTypeArguments ( parentNode : Node , typeArguments : NodeArray < TypeNode > | undefined ) {
4257- emitList ( parentNode , typeArguments , ListFormat . TypeArguments , parenthesizer . parenthesizeMemberOfElementType ) ;
4264+ emitList ( parentNode , typeArguments , ListFormat . TypeArguments , typeArgumentParenthesizerRuleSelector ) ;
42584265 }
42594266
42604267 function emitTypeParameters ( parentNode : SignatureDeclaration | InterfaceDeclaration | TypeAliasDeclaration | ClassDeclaration | ClassExpression , typeParameters : NodeArray < TypeParameterDeclaration > | undefined ) {
@@ -4322,15 +4329,15 @@ namespace ts {
43224329 }
43234330 }
43244331
4325- function emitList ( parentNode : Node | undefined , children : NodeArray < Node > | undefined , format : ListFormat , parenthesizerRule ?: ( node : Node ) => Node , start ?: number , count ?: number ) {
4332+ function emitList ( parentNode : Node | undefined , children : NodeArray < Node > | undefined , format : ListFormat , parenthesizerRule ?: ParenthesizerRuleOrSelector < Node > , start ?: number , count ?: number ) {
43264333 emitNodeList ( emit , parentNode , children , format , parenthesizerRule , start , count ) ;
43274334 }
43284335
4329- function emitExpressionList ( parentNode : Node | undefined , children : NodeArray < Node > | undefined , format : ListFormat , parenthesizerRule ?: ( node : Expression ) => Expression , start ?: number , count ?: number ) {
4336+ function emitExpressionList ( parentNode : Node | undefined , children : NodeArray < Node > | undefined , format : ListFormat , parenthesizerRule ?: ParenthesizerRuleOrSelector < Expression > , start ?: number , count ?: number ) {
43304337 emitNodeList ( emitExpression , parentNode , children , format , parenthesizerRule , start , count ) ;
43314338 }
43324339
4333- 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 ) {
4340+ 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 ) {
43344341 const isUndefined = children === undefined ;
43354342 if ( isUndefined && format & ListFormat . OptionalIfUndefined ) {
43364343 return ;
@@ -4386,6 +4393,8 @@ namespace ts {
43864393 increaseIndent ( ) ;
43874394 }
43884395
4396+ const emitListItem = getEmitListItem ( emit , parenthesizerRule ) ;
4397+
43894398 // Emit each child.
43904399 let previousSibling : Node | undefined ;
43914400 let previousSourceFileTextKind : ReturnType < typeof recordBundleFileInternalSectionStart > ;
@@ -4441,12 +4450,7 @@ namespace ts {
44414450 }
44424451
44434452 nextListElementPos = child . pos ;
4444- if ( emit . length === 1 ) {
4445- emit ( child ) ;
4446- }
4447- else {
4448- emit ( child , parenthesizerRule ) ;
4449- }
4453+ emitListItem ( child , emit , parenthesizerRule , i ) ;
44504454
44514455 if ( shouldDecreaseIndentAfterEmit ) {
44524456 decreaseIndent ( ) ;
@@ -5888,4 +5892,30 @@ namespace ts {
58885892 CountMask = 0x0FFFFFFF , // Temp variable counter
58895893 _i = 0x10000000 , // Use/preference flag for '_i'
58905894 }
5895+
5896+ interface OrdinalParentheizerRuleSelector < T extends Node > {
5897+ select ( index : number ) : ( ( node : T ) => T ) | undefined ;
5898+ }
5899+
5900+ type ParenthesizerRule < T extends Node > = ( node : T ) => T ;
5901+
5902+ type ParenthesizerRuleOrSelector < T extends Node > = OrdinalParentheizerRuleSelector < T > | ParenthesizerRule < T > ;
5903+
5904+ function emitListItemNoParenthesizer ( node : Node , emit : ( node : Node , parenthesizerRule ?: ( ( node : Node ) => Node ) | undefined ) => void , _parenthesizerRule : ParenthesizerRuleOrSelector < Node > | undefined , _index : number ) {
5905+ emit ( node ) ;
5906+ }
5907+
5908+ function emitListItemWithParenthesizerRuleSelector ( node : Node , emit : ( node : Node , parenthesizerRule ?: ( ( node : Node ) => Node ) | undefined ) => void , parenthesizerRuleSelector : OrdinalParentheizerRuleSelector < Node > , index : number ) {
5909+ emit ( node , parenthesizerRuleSelector . select ( index ) ) ;
5910+ }
5911+
5912+ function emitListItemWithParenthesizerRule ( node : Node , emit : ( node : Node , parenthesizerRule ?: ( ( node : Node ) => Node ) | undefined ) => void , parenthesizerRule : ParenthesizerRule < Node > | undefined , _index : number ) {
5913+ emit ( node , parenthesizerRule ) ;
5914+ }
5915+
5916+ 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 {
5917+ return emit . length === 1 ? emitListItemNoParenthesizer :
5918+ typeof parenthesizerRule === "object" ? emitListItemWithParenthesizerRuleSelector :
5919+ emitListItemWithParenthesizerRule ;
5920+ }
58915921}
0 commit comments