@@ -66,7 +66,7 @@ export const enum ApiViewTokenKind {
6666 DeprecatedRangeStart = 13 ,
6767 DeprecatedRangeEnd = 14 ,
6868 SkipDiffRangeStart = 15 ,
69- SkipDiffRangeEnd = 16
69+ SkipDiffRangeEnd = 16 ,
7070}
7171
7272export interface ApiViewToken {
@@ -138,7 +138,7 @@ export class ApiView {
138138 }
139139
140140 trim ( ) {
141- let last = this . tokens [ this . tokens . length - 1 ]
141+ let last = this . tokens [ this . tokens . length - 1 ] ;
142142 while ( last ) {
143143 if ( last . Kind === ApiViewTokenKind . Whitespace ) {
144144 this . tokens . pop ( ) ;
@@ -297,7 +297,7 @@ export class ApiView {
297297 this . tokens . push ( {
298298 Kind : ApiViewTokenKind . StringLiteral ,
299299 Value : `\u0022${ value } \u0022` ,
300- } ) ;
300+ } ) ;
301301 } else {
302302 this . punctuation ( `"""` ) ;
303303 this . newline ( ) ;
@@ -359,7 +359,7 @@ export class ApiView {
359359 const nsModel = new NamespaceModel ( namespaceName , ns , program ) ;
360360 if ( nsModel . shouldEmit ( ) ) {
361361 this . tokenizeNamespaceModel ( nsModel ) ;
362- this . buildNavigation ( nsModel ) ;
362+ this . buildNavigation ( nsModel ) ;
363363 }
364364 }
365365 }
@@ -379,6 +379,7 @@ export class ApiView {
379379
380380 tokenize ( node : BaseNode ) {
381381 let obj ;
382+ let isExpanded = false ;
382383 switch ( node . kind ) {
383384 case SyntaxKind . AliasStatement :
384385 obj = node as AliasStatementNode ;
@@ -448,6 +449,7 @@ export class ApiView {
448449 break ;
449450 case SyntaxKind . DirectiveExpression :
450451 obj = node as DirectiveExpressionNode ;
452+ this . namespaceStack . push ( generateId ( node ) ! ) ;
451453 this . keyword ( `#${ obj . target . sv } ` , false , true ) ;
452454 for ( const arg of obj . arguments ) {
453455 switch ( arg . kind ) {
@@ -462,6 +464,7 @@ export class ApiView {
462464 }
463465 }
464466 this . newline ( ) ;
467+ this . namespaceStack . pop ( ) ;
465468 break ;
466469 case SyntaxKind . EmptyStatement :
467470 throw new Error ( `Case "EmptyStatement" not implemented` ) ;
@@ -591,10 +594,30 @@ export class ApiView {
591594 this . punctuation ( "]" , true , false ) ;
592595 break ;
593596 case SyntaxKind . TypeReference :
597+
598+ // if (isExpanded) {
599+ // this.newline();
600+ // this.indent();
601+ // }
602+ // if (obj.name) {
603+ // this.text(obj.name.sv);
604+ // this.punctuation("=", true, true);
605+ // }
606+ // if (isExpanded) {
607+ // this.tokenizeModelExpressionExpanded(obj.argument as ModelExpressionNode, false, false);
608+ // this.deindent();
609+ // } else {
610+ // this.tokenize(obj.argument);
611+ // }
594612 obj = node as TypeReferenceNode ;
613+ isExpanded = this . isTemplateExpanded ( obj ) ;
595614 this . tokenizeIdentifier ( obj . target , "reference" ) ;
596615 if ( obj . arguments . length ) {
597- this . punctuation ( "<" , false , false ) ;
616+ this . punctuation ( "<" , false , false ) ;
617+ if ( isExpanded ) {
618+ this . newline ( ) ;
619+ this . indent ( ) ;
620+ }
598621 for ( let x = 0 ; x < obj . arguments . length ; x ++ ) {
599622 const arg = obj . arguments [ x ] ;
600623 this . tokenize ( arg ) ;
@@ -610,7 +633,7 @@ export class ApiView {
610633 for ( let x = 0 ; x < obj . options . length ; x ++ ) {
611634 const opt = obj . options [ x ] ;
612635 this . tokenize ( opt ) ;
613- if ( x !== obj . options . length - 1 ) {
636+ if ( x !== obj . options . length - 1 ) {
614637 this . punctuation ( "|" , true , true ) ;
615638 }
616639 }
@@ -635,20 +658,20 @@ export class ApiView {
635658 break ;
636659 case SyntaxKind . TemplateArgument :
637660 obj = node as TemplateArgumentNode ;
638- const isExpanded = obj . argument . kind === SyntaxKind . ModelExpression ;
661+ isExpanded = false ; // obj.argument.kind === SyntaxKind.ModelExpression;
639662 if ( isExpanded ) {
640- this . newline ( ) ;
641- this . indent ( ) ;
663+ this . newline ( ) ;
664+ this . indent ( ) ;
642665 }
643666 if ( obj . name ) {
644- this . text ( obj . name . sv ) ;
645- this . punctuation ( "=" , true , true ) ;
667+ this . text ( obj . name . sv ) ;
668+ this . punctuation ( "=" , true , true ) ;
646669 }
647670 if ( isExpanded ) {
648- this . tokenizeModelExpressionExpanded ( obj . argument as ModelExpressionNode , false , false ) ;
649- this . deindent ( ) ;
671+ this . tokenizeModelExpressionExpanded ( obj . argument as ModelExpressionNode , false , false ) ;
672+ this . deindent ( ) ;
650673 } else {
651- this . tokenize ( obj . argument ) ;
674+ this . tokenize ( obj . argument ) ;
652675 }
653676 break ;
654677 case SyntaxKind . StringTemplateExpression :
@@ -796,7 +819,7 @@ export class ApiView {
796819 for ( let x = 0 ; x < node . operations . length ; x ++ ) {
797820 const op = node . operations [ x ] ;
798821 this . tokenizeOperationStatement ( op , true ) ;
799- this . blankLines ( ( x !== node . operations . length - 1 ) ? 1 : 0 ) ;
822+ this . blankLines ( x !== node . operations . length - 1 ? 1 : 0 ) ;
800823 }
801824 this . endGroup ( ) ;
802825 this . namespaceStack . pop ( ) ;
@@ -881,7 +904,7 @@ export class ApiView {
881904 if ( isOperationSignature ) {
882905 if ( x !== node . properties . length - 1 ) {
883906 this . punctuation ( "," , false , true ) ;
884- }
907+ }
885908 } else {
886909 this . punctuation ( ";" ) ;
887910 }
@@ -892,7 +915,11 @@ export class ApiView {
892915 }
893916 }
894917
895- private tokenizeModelExpressionExpanded ( node : ModelExpressionNode , isOperationSignature : boolean , leadingNewline : boolean ) {
918+ private tokenizeModelExpressionExpanded (
919+ node : ModelExpressionNode ,
920+ isOperationSignature : boolean ,
921+ leadingNewline : boolean ,
922+ ) {
896923 if ( node . properties . length ) {
897924 if ( leadingNewline ) {
898925 this . blankLines ( 0 ) ;
@@ -901,7 +928,7 @@ export class ApiView {
901928 if ( ! isOperationSignature ) {
902929 this . punctuation ( "{" , false , false ) ;
903930 this . blankLines ( 0 ) ;
904- this . indent ( ) ;
931+ this . indent ( ) ;
905932 }
906933 this . namespaceStack . push ( "anonymous" ) ;
907934 for ( let x = 0 ; x < node . properties . length ; x ++ ) {
@@ -918,8 +945,9 @@ export class ApiView {
918945 this . namespaceStack . pop ( ) ;
919946 if ( isOperationSignature ) {
920947 if ( x !== node . properties . length - 1 ) {
948+ this . trim ( ) ;
921949 this . renderPunctuation ( "," ) ;
922- }
950+ }
923951 } else {
924952 this . renderPunctuation ( ";" ) ;
925953 }
@@ -930,27 +958,22 @@ export class ApiView {
930958 if ( ! isOperationSignature ) {
931959 this . deindent ( ) ;
932960 this . punctuation ( "}" , false , false ) ;
933- this . blankLines ( 0 ) ;
961+ this . blankLines ( 0 ) ;
934962 }
935963 this . trim ( ) ;
936964 if ( leadingNewline ) {
937965 this . deindent ( ) ;
938966 }
939-
940967 } else if ( ! isOperationSignature ) {
941968 this . punctuation ( "{}" , true , false ) ;
942969 }
943970 }
944971
945- private tokenizeModelExpression (
946- node : ModelExpressionNode ,
947- isOperationSignature : boolean ,
948- inline : boolean
949- ) {
972+ private tokenizeModelExpression ( node : ModelExpressionNode , isOperationSignature : boolean , inline : boolean ) {
950973 if ( inline ) {
951- this . tokenizeModelExpressionInline ( node , isOperationSignature )
974+ this . tokenizeModelExpressionInline ( node , isOperationSignature ) ;
952975 } else {
953- this . tokenizeModelExpressionExpanded ( node , isOperationSignature , true )
976+ this . tokenizeModelExpressionExpanded ( node , isOperationSignature , true ) ;
954977 }
955978 }
956979
@@ -970,7 +993,7 @@ export class ApiView {
970993 private tokenizeNamespaceModel ( model : NamespaceModel ) {
971994 this . namespaceStack . push ( model . name ) ;
972995 if ( model . node . kind === SyntaxKind . NamespaceStatement ) {
973- this . tokenizeDecoratorsAndDirectives ( model . node . decorators , model . node . directives , false ) ;
996+ this . tokenizeDecoratorsAndDirectives ( model . node . decorators , model . node . directives , false ) ;
974997 }
975998 this . keyword ( "namespace" , false , true ) ;
976999 this . typeDeclaration ( model . name , this . namespaceStack . value ( ) , true ) ;
@@ -992,19 +1015,23 @@ export class ApiView {
9921015 this . blankLines ( 1 ) ;
9931016 }
9941017 for ( const node of model . aliases . values ( ) ) {
995- this . tokenize ( node ) ;
996- this . punctuation ( ";" ) ;
997- this . blankLines ( 1 ) ;
998- }
1018+ this . tokenize ( node ) ;
1019+ this . punctuation ( ";" ) ;
1020+ this . blankLines ( 1 ) ;
1021+ }
9991022 this . endGroup ( ) ;
10001023 this . blankLines ( 1 ) ;
10011024 this . namespaceStack . pop ( ) ;
10021025 }
10031026
1004- private tokenizeDecoratorsAndDirectives ( decorators : readonly DecoratorExpressionNode [ ] | undefined , directives : readonly DirectiveExpressionNode [ ] | undefined , inline : boolean ) {
1005- const docDecorators = [ "doc" , "summary" , "example" ]
1027+ private tokenizeDecoratorsAndDirectives (
1028+ decorators : readonly DecoratorExpressionNode [ ] | undefined ,
1029+ directives : readonly DirectiveExpressionNode [ ] | undefined ,
1030+ inline : boolean ,
1031+ ) {
1032+ const docDecorators = [ "doc" , "summary" , "example" ] ;
10061033 if ( ( directives || [ ] ) . length === 0 && ( decorators || [ ] ) . length === 0 ) {
1007- return ;
1034+ return ;
10081035 }
10091036 for ( const directive of directives ?? [ ] ) {
10101037 this . tokenize ( directive ) ;
@@ -1028,11 +1055,11 @@ export class ApiView {
10281055 // render each decorator
10291056 for ( const node of decorators || [ ] ) {
10301057 this . namespaceStack . push ( generateId ( node ) ! ) ;
1031- const isDoc = docDecorators . includes ( ( node . target as IdentifierNode ) . sv )
1058+ const isDoc = docDecorators . includes ( ( node . target as IdentifierNode ) . sv ) ;
10321059 if ( isDoc ) {
10331060 this . tokens . push ( {
1034- Kind : ApiViewTokenKind . DocumentRangeStart
1035- } )
1061+ Kind : ApiViewTokenKind . DocumentRangeStart ,
1062+ } ) ;
10361063 }
10371064 this . tokenize ( node ) ;
10381065 if ( inline ) {
@@ -1044,8 +1071,8 @@ export class ApiView {
10441071 }
10451072 if ( isDoc ) {
10461073 this . tokens . push ( {
1047- Kind : ApiViewTokenKind . DocumentRangeEnd
1048- } )
1074+ Kind : ApiViewTokenKind . DocumentRangeEnd ,
1075+ } ) ;
10491076 }
10501077 }
10511078 }
@@ -1061,7 +1088,7 @@ export class ApiView {
10611088
10621089 private tokenizeIdentifier (
10631090 node : IdentifierNode | MemberExpressionNode | StringLiteralNode ,
1064- style : "declaration" | "reference" | "member" | "keyword"
1091+ style : "declaration" | "reference" | "member" | "keyword" ,
10651092 ) {
10661093 switch ( node . kind ) {
10671094 case SyntaxKind . MemberExpression :
@@ -1099,7 +1126,7 @@ export class ApiView {
10991126 this . member ( this . getRawText ( node ) ) ;
11001127 break ;
11011128 case "keyword" :
1102- this . keyword ( node . sv )
1129+ this . keyword ( node . sv ) ;
11031130 break ;
11041131 }
11051132 }
@@ -1109,10 +1136,17 @@ export class ApiView {
11091136 return getSourceLocation ( node ) . file . text . slice ( node . pos , node . end ) ;
11101137 }
11111138
1139+ private isTemplateExpanded ( node : TypeReferenceNode ) : boolean {
1140+ if ( node . arguments . length === 0 ) {
1141+ return false ;
1142+ }
1143+ const first = node . arguments [ 0 ] ;
1144+ return first . argument . kind === SyntaxKind . ModelExpression ;
1145+ }
11121146
11131147 private tokenizeTemplateParameters ( nodes : readonly TemplateParameterDeclarationNode [ ] ) {
11141148 if ( nodes . length ) {
1115- this . punctuation ( "<" , false , false ) ;
1149+ this . punctuation ( "<" , false , false ) ;
11161150 for ( let x = 0 ; x < nodes . length ; x ++ ) {
11171151 const param = nodes [ x ] ;
11181152 this . tokenize ( param ) ;
@@ -1130,7 +1164,10 @@ export class ApiView {
11301164 const offset = this . tokens . length ;
11311165 this . tokenize ( node . returnType ) ;
11321166 const returnTokens = this . tokens . slice ( offset ) ;
1133- const returnTypeString = returnTokens . filter ( ( x ) => x . Value ) . flatMap ( ( x ) => x . Value ) . join ( "" ) ;
1167+ const returnTypeString = returnTokens
1168+ . filter ( ( x ) => x . Value )
1169+ . flatMap ( ( x ) => x . Value )
1170+ . join ( "" ) ;
11341171 this . namespaceStack . push ( returnTypeString ) ;
11351172 this . lineMarker ( ) ;
11361173 this . namespaceStack . pop ( ) ;
@@ -1154,13 +1191,6 @@ export class ApiView {
11541191 }
11551192
11561193 private renderPunctuation ( punctuation : string ) {
1157- const last = this . tokens . pop ( ) ! ;
1158- if ( last ?. Kind === ApiViewTokenKind . Whitespace ) {
1159- // hacky workaround to ensure comma is after trailing bracket for expanded anonymous models
1160- this . tokens . pop ( ) ;
1161- } else {
1162- this . tokens . push ( last ) ;
1163- }
11641194 this . punctuation ( punctuation , false , true ) ;
11651195 }
11661196
@@ -1181,7 +1211,7 @@ export class ApiView {
11811211 Diagnostics : this . diagnostics ,
11821212 VersionString : this . versionString ,
11831213 Language : "TypeSpec" ,
1184- CrossLanguagePackageId : this . crossLanguagePackageId
1214+ CrossLanguagePackageId : this . crossLanguagePackageId ,
11851215 } ;
11861216 }
11871217
@@ -1217,4 +1247,4 @@ export class NamespaceStack {
12171247 reset ( ) {
12181248 this . stack = Array < string > ( ) ;
12191249 }
1220- } ;
1250+ }
0 commit comments