@@ -406,6 +406,14 @@ namespace ts {
406406 setWriter ( /*output*/ undefined ) ;
407407 }
408408
409+ // TODO: Should this just be `emit`?
410+ // See https://github.com/Microsoft/TypeScript/pull/18284#discussion_r137611034
411+ function emitIfPresent ( node : Node | undefined ) {
412+ if ( node ) {
413+ emit ( node ) ;
414+ }
415+ }
416+
409417 function emit ( node : Node ) {
410418 pipelineEmitWithNotification ( EmitHint . Unspecified , node ) ;
411419 }
@@ -451,6 +459,7 @@ namespace ts {
451459 case EmitHint . SourceFile : return pipelineEmitSourceFile ( node ) ;
452460 case EmitHint . IdentifierName : return pipelineEmitIdentifierName ( node ) ;
453461 case EmitHint . Expression : return pipelineEmitExpression ( node ) ;
462+ case EmitHint . MappedTypeParameter : return emitMappedTypeParameter ( cast ( node , isTypeParameterDeclaration ) ) ;
454463 case EmitHint . Unspecified : return pipelineEmitUnspecified ( node ) ;
455464 }
456465 }
@@ -465,6 +474,12 @@ namespace ts {
465474 emitIdentifier ( < Identifier > node ) ;
466475 }
467476
477+ function emitMappedTypeParameter ( node : TypeParameterDeclaration ) : void {
478+ emit ( node . name ) ;
479+ write ( " in " ) ;
480+ emit ( node . constraint ) ;
481+ }
482+
468483 function pipelineEmitUnspecified ( node : Node ) : void {
469484 const kind = node . kind ;
470485
@@ -898,9 +913,9 @@ namespace ts {
898913 function emitParameter ( node : ParameterDeclaration ) {
899914 emitDecorators ( node , node . decorators ) ;
900915 emitModifiers ( node , node . modifiers ) ;
901- writeIfPresent ( node . dotDotDotToken , "..." ) ;
916+ emitIfPresent ( node . dotDotDotToken ) ;
902917 emit ( node . name ) ;
903- writeIfPresent ( node . questionToken , "?" ) ;
918+ emitIfPresent ( node . questionToken ) ;
904919 emitWithPrefix ( ": " , node . type ) ;
905920 emitExpressionWithPrefix ( " = " , node . initializer ) ;
906921 }
@@ -918,7 +933,7 @@ namespace ts {
918933 emitDecorators ( node , node . decorators ) ;
919934 emitModifiers ( node , node . modifiers ) ;
920935 emit ( node . name ) ;
921- writeIfPresent ( node . questionToken , "?" ) ;
936+ emitIfPresent ( node . questionToken ) ;
922937 emitWithPrefix ( ": " , node . type ) ;
923938 write ( ";" ) ;
924939 }
@@ -927,7 +942,7 @@ namespace ts {
927942 emitDecorators ( node , node . decorators ) ;
928943 emitModifiers ( node , node . modifiers ) ;
929944 emit ( node . name ) ;
930- writeIfPresent ( node . questionToken , "?" ) ;
945+ emitIfPresent ( node . questionToken ) ;
931946 emitWithPrefix ( ": " , node . type ) ;
932947 emitExpressionWithPrefix ( " = " , node . initializer ) ;
933948 write ( ";" ) ;
@@ -937,7 +952,7 @@ namespace ts {
937952 emitDecorators ( node , node . decorators ) ;
938953 emitModifiers ( node , node . modifiers ) ;
939954 emit ( node . name ) ;
940- writeIfPresent ( node . questionToken , "?" ) ;
955+ emitIfPresent ( node . questionToken ) ;
941956 emitTypeParameters ( node , node . typeParameters ) ;
942957 emitParameters ( node , node . parameters ) ;
943958 emitWithPrefix ( ": " , node . type ) ;
@@ -947,9 +962,9 @@ namespace ts {
947962 function emitMethodDeclaration ( node : MethodDeclaration ) {
948963 emitDecorators ( node , node . decorators ) ;
949964 emitModifiers ( node , node . modifiers ) ;
950- writeIfPresent ( node . asteriskToken , "*" ) ;
965+ emitIfPresent ( node . asteriskToken ) ;
951966 emit ( node . name ) ;
952- writeIfPresent ( node . questionToken , "?" ) ;
967+ emitIfPresent ( node . questionToken ) ;
953968 emitSignatureAndBody ( node , emitSignatureHead ) ;
954969 }
955970
@@ -1035,10 +1050,8 @@ namespace ts {
10351050
10361051 function emitTypeLiteral ( node : TypeLiteralNode ) {
10371052 write ( "{" ) ;
1038- // If the literal is empty, do not add spaces between braces.
1039- if ( node . members . length > 0 ) {
1040- emitList ( node , node . members , getEmitFlags ( node ) & EmitFlags . SingleLine ? ListFormat . SingleLineTypeLiteralMembers : ListFormat . MultiLineTypeLiteralMembers ) ;
1041- }
1053+ const flags = getEmitFlags ( node ) & EmitFlags . SingleLine ? ListFormat . SingleLineTypeLiteralMembers : ListFormat . MultiLineTypeLiteralMembers ;
1054+ emitList ( node , node . members , flags | ListFormat . NoSpaceIfEmpty ) ;
10421055 write ( "}" ) ;
10431056 }
10441057
@@ -1094,13 +1107,16 @@ namespace ts {
10941107 writeLine ( ) ;
10951108 increaseIndent ( ) ;
10961109 }
1097- writeIfPresent ( node . readonlyToken , "readonly " ) ;
1110+ if ( node . readonlyToken ) {
1111+ emit ( node . readonlyToken ) ;
1112+ write ( " " ) ;
1113+ }
1114+
10981115 write ( "[" ) ;
1099- emit ( node . typeParameter . name ) ;
1100- write ( " in " ) ;
1101- emit ( node . typeParameter . constraint ) ;
1116+ pipelineEmitWithNotification ( EmitHint . MappedTypeParameter , node . typeParameter ) ;
11021117 write ( "]" ) ;
1103- writeIfPresent ( node . questionToken , "?" ) ;
1118+
1119+ emitIfPresent ( node . questionToken ) ;
11041120 write ( ": " ) ;
11051121 emit ( node . type ) ;
11061122 write ( ";" ) ;
@@ -1148,7 +1164,7 @@ namespace ts {
11481164
11491165 function emitBindingElement ( node : BindingElement ) {
11501166 emitWithSuffix ( node . propertyName , ": " ) ;
1151- writeIfPresent ( node . dotDotDotToken , "..." ) ;
1167+ emitIfPresent ( node . dotDotDotToken ) ;
11521168 emit ( node . name ) ;
11531169 emitExpressionWithPrefix ( " = " , node . initializer ) ;
11541170 }
@@ -1159,33 +1175,22 @@ namespace ts {
11591175
11601176 function emitArrayLiteralExpression ( node : ArrayLiteralExpression ) {
11611177 const elements = node . elements ;
1162- if ( elements . length === 0 ) {
1163- write ( "[]" ) ;
1164- }
1165- else {
1166- const preferNewLine = node . multiLine ? ListFormat . PreferNewLine : ListFormat . None ;
1167- emitExpressionList ( node , elements , ListFormat . ArrayLiteralExpressionElements | preferNewLine ) ;
1168- }
1178+ const preferNewLine = node . multiLine ? ListFormat . PreferNewLine : ListFormat . None ;
1179+ emitExpressionList ( node , elements , ListFormat . ArrayLiteralExpressionElements | preferNewLine ) ;
11691180 }
11701181
11711182 function emitObjectLiteralExpression ( node : ObjectLiteralExpression ) {
1172- const properties = node . properties ;
1173- if ( properties . length === 0 ) {
1174- write ( "{}" ) ;
1183+ const indentedFlag = getEmitFlags ( node ) & EmitFlags . Indented ;
1184+ if ( indentedFlag ) {
1185+ increaseIndent ( ) ;
11751186 }
1176- else {
1177- const indentedFlag = getEmitFlags ( node ) & EmitFlags . Indented ;
1178- if ( indentedFlag ) {
1179- increaseIndent ( ) ;
1180- }
11811187
1182- const preferNewLine = node . multiLine ? ListFormat . PreferNewLine : ListFormat . None ;
1183- const allowTrailingComma = currentSourceFile . languageVersion >= ScriptTarget . ES5 ? ListFormat . AllowTrailingComma : ListFormat . None ;
1184- emitList ( node , properties , ListFormat . ObjectLiteralExpressionProperties | allowTrailingComma | preferNewLine ) ;
1188+ const preferNewLine = node . multiLine ? ListFormat . PreferNewLine : ListFormat . None ;
1189+ const allowTrailingComma = currentSourceFile . languageVersion >= ScriptTarget . ES5 ? ListFormat . AllowTrailingComma : ListFormat . None ;
1190+ emitList ( node , node . properties , ListFormat . ObjectLiteralExpressionProperties | allowTrailingComma | preferNewLine ) ;
11851191
1186- if ( indentedFlag ) {
1187- decreaseIndent ( ) ;
1188- }
1192+ if ( indentedFlag ) {
1193+ decreaseIndent ( ) ;
11891194 }
11901195 }
11911196
@@ -1286,7 +1291,8 @@ namespace ts {
12861291 emitTypeParameters ( node , node . typeParameters ) ;
12871292 emitParametersForArrow ( node , node . parameters ) ;
12881293 emitWithPrefix ( ": " , node . type ) ;
1289- write ( " =>" ) ;
1294+ write ( " " ) ;
1295+ emit ( node . equalsGreaterThanToken ) ;
12901296 }
12911297
12921298 function emitDeleteExpression ( node : DeleteExpression ) {
@@ -1364,13 +1370,13 @@ namespace ts {
13641370
13651371 emitExpression ( node . condition ) ;
13661372 increaseIndentIf ( indentBeforeQuestion , " " ) ;
1367- write ( "?" ) ;
1373+ emit ( node . questionToken ) ;
13681374 increaseIndentIf ( indentAfterQuestion , " " ) ;
13691375 emitExpression ( node . whenTrue ) ;
13701376 decreaseIndentIf ( indentBeforeQuestion , indentAfterQuestion ) ;
13711377
13721378 increaseIndentIf ( indentBeforeColon , " " ) ;
1373- write ( ":" ) ;
1379+ emit ( node . colonToken ) ;
13741380 increaseIndentIf ( indentAfterColon , " " ) ;
13751381 emitExpression ( node . whenFalse ) ;
13761382 decreaseIndentIf ( indentBeforeColon , indentAfterColon ) ;
@@ -1382,7 +1388,8 @@ namespace ts {
13821388 }
13831389
13841390 function emitYieldExpression ( node : YieldExpression ) {
1385- write ( node . asteriskToken ? "yield*" : "yield" ) ;
1391+ write ( "yield" ) ;
1392+ emit ( node . asteriskToken ) ;
13861393 emitExpressionWithPrefix ( " " , node . expression ) ;
13871394 }
13881395
@@ -1662,7 +1669,9 @@ namespace ts {
16621669 function emitFunctionDeclarationOrExpression ( node : FunctionDeclaration | FunctionExpression ) {
16631670 emitDecorators ( node , node . decorators ) ;
16641671 emitModifiers ( node , node . modifiers ) ;
1665- write ( node . asteriskToken ? "function* " : "function " ) ;
1672+ write ( "function" ) ;
1673+ emitIfPresent ( node . asteriskToken ) ;
1674+ write ( " " ) ;
16661675 emitIdentifierName ( node . name ) ;
16671676 emitSignatureAndBody ( node , emitSignatureHead ) ;
16681677 }
@@ -2068,9 +2077,7 @@ namespace ts {
20682077 function emitJsxExpression ( node : JsxExpression ) {
20692078 if ( node . expression ) {
20702079 write ( "{" ) ;
2071- if ( node . dotDotDotToken ) {
2072- write ( "..." ) ;
2073- }
2080+ emitIfPresent ( node . dotDotDotToken ) ;
20742081 emitExpression ( node . expression ) ;
20752082 write ( "}" ) ;
20762083 }
@@ -2128,13 +2135,12 @@ namespace ts {
21282135 emitTrailingCommentsOfPosition ( statements . pos ) ;
21292136 }
21302137
2138+ let format = ListFormat . CaseOrDefaultClauseStatements ;
21312139 if ( emitAsSingleStatement ) {
21322140 write ( " " ) ;
2133- emit ( statements [ 0 ] ) ;
2134- }
2135- else {
2136- emitList ( parentNode , statements , ListFormat . CaseOrDefaultClauseStatements ) ;
2141+ format &= ~ ( ListFormat . MultiLine | ListFormat . Indented ) ;
21372142 }
2143+ emitList ( parentNode , statements , format ) ;
21382144 }
21392145
21402146 function emitHeritageClause ( node : HeritageClause ) {
@@ -2384,7 +2390,7 @@ namespace ts {
23842390
23852391 function emitParametersForArrow ( parentNode : FunctionTypeNode | ArrowFunction , parameters : NodeArray < ParameterDeclaration > ) {
23862392 if ( canEmitSimpleArrowHead ( parentNode , parameters ) ) {
2387- emit ( parameters [ 0 ] ) ;
2393+ emitList ( parentNode , parameters , ListFormat . Parameters & ~ ListFormat . Parenthesis ) ;
23882394 }
23892395 else {
23902396 emitParameters ( parentNode , parameters ) ;
@@ -2427,7 +2433,7 @@ namespace ts {
24272433 if ( format & ListFormat . MultiLine ) {
24282434 writeLine ( ) ;
24292435 }
2430- else if ( format & ListFormat . SpaceBetweenBraces ) {
2436+ else if ( format & ListFormat . SpaceBetweenBraces && ! ( format & ListFormat . NoSpaceIfEmpty ) ) {
24312437 write ( " " ) ;
24322438 }
24332439 }
@@ -2568,12 +2574,6 @@ namespace ts {
25682574 }
25692575 }
25702576
2571- function writeIfPresent ( node : Node , text : string ) {
2572- if ( node ) {
2573- write ( text ) ;
2574- }
2575- }
2576-
25772577 function writeToken ( token : SyntaxKind , pos : number , contextNode ?: Node ) {
25782578 return onEmitSourceMapOfToken
25792579 ? onEmitSourceMapOfToken ( contextNode , token , pos , writeTokenText )
@@ -2584,7 +2584,7 @@ namespace ts {
25842584 if ( onBeforeEmitToken ) {
25852585 onBeforeEmitToken ( node ) ;
25862586 }
2587- writeTokenText ( node . kind ) ;
2587+ write ( tokenToString ( node . kind ) ) ;
25882588 if ( onAfterEmitToken ) {
25892589 onAfterEmitToken ( node ) ;
25902590 }
@@ -3107,6 +3107,9 @@ namespace ts {
31073107 NoTrailingNewLine = 1 << 16 , // Do not emit a trailing NewLine for a MultiLine list.
31083108 NoInterveningComments = 1 << 17 , // Do not emit comments between each node
31093109
3110+ NoSpaceIfEmpty = 1 << 18 , // If the literal is empty, do not add spaces between braces.
3111+ SingleElement = 1 << 19 ,
3112+
31103113 // Precomputed Formats
31113114 Modifiers = SingleLine | SpaceBetweenSiblings | NoInterveningComments ,
31123115 HeritageClauses = SingleLine | SpaceBetweenSiblings ,
@@ -3118,7 +3121,7 @@ namespace ts {
31183121 IntersectionTypeConstituents = AmpersandDelimited | SpaceBetweenSiblings | SingleLine ,
31193122 ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings ,
31203123 ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited | SpaceBetweenSiblings ,
3121- ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces ,
3124+ ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces | NoSpaceIfEmpty ,
31223125 ArrayLiteralExpressionElements = PreserveLines | CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | Indented | SquareBrackets ,
31233126 CommaListElements = CommaDelimited | SpaceBetweenSiblings | SingleLine ,
31243127 CallExpressionArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis ,
0 commit comments