@@ -414,7 +414,7 @@ export function modelGenerics (node: TypeParameterDeclaration): string {
414
414
* which returns an array that only contains the member of the Enum.
415
415
*/
416
416
export function modelEnumDeclaration ( declaration : EnumDeclaration ) : model . Enum {
417
- return {
417
+ const type : model . Enum = {
418
418
specLocation : sourceLocation ( declaration ) ,
419
419
name : {
420
420
name : declaration . getName ( ) ,
@@ -433,6 +433,13 @@ export function modelEnumDeclaration (declaration: EnumDeclaration): model.Enum
433
433
return member
434
434
} )
435
435
}
436
+
437
+ const tags = parseJsDocTags ( declaration . getJsDocs ( ) )
438
+ if ( typeof tags . non_exhaustive === 'string' ) {
439
+ type . isOpen = true
440
+ }
441
+
442
+ return type
436
443
}
437
444
438
445
/**
@@ -632,7 +639,7 @@ export function hoistTypeAnnotations (type: model.TypeDefinition, jsDocs: JSDoc[
632
639
// We want to enforce a single jsDoc block.
633
640
assert ( jsDocs , jsDocs . length < 2 , 'Use a single multiline jsDoc block instead of multiple single line blocks' )
634
641
635
- const validTags = [ 'class_serializer' , 'doc_url' , 'doc_id' , 'behavior' , 'variants' , 'variant' , 'shortcut_property' , 'codegen_names' ]
642
+ const validTags = [ 'class_serializer' , 'doc_url' , 'doc_id' , 'behavior' , 'variants' , 'variant' , 'shortcut_property' , 'codegen_names' , 'non_exhaustive' ]
636
643
const tags = parseJsDocTags ( jsDocs )
637
644
if ( jsDocs . length === 1 ) {
638
645
const description = jsDocs [ 0 ] . getDescription ( )
@@ -650,6 +657,8 @@ export function hoistTypeAnnotations (type: model.TypeDefinition, jsDocs: JSDoc[
650
657
}
651
658
} else if ( tag === 'variants' ) {
652
659
} else if ( tag === 'variant' ) {
660
+ } else if ( tag === 'non_exhaustive' ) {
661
+ assert ( jsDocs , typeof tags . variants === 'string' , '@non_exhaustive only applies to enums and @variants' )
653
662
} else if ( tag === 'doc_url' ) {
654
663
assert ( jsDocs , isValidUrl ( value ) , '@doc_url is not a valid url' )
655
664
type . docUrl = value
@@ -924,13 +933,21 @@ export function parseVariantsTag (jsDoc: JSDoc[]): model.Variants | undefined {
924
933
return undefined
925
934
}
926
935
936
+ const nonExhaustive = ( typeof tags . non_exhaustive === 'string' ) ? true : undefined
937
+
927
938
const [ type , ...values ] = tags . variants . split ( ' ' )
928
939
if ( type === 'external' ) {
929
- return { kind : 'external_tag' }
940
+ return {
941
+ kind : 'external_tag' ,
942
+ nonExhaustive : nonExhaustive
943
+ }
930
944
}
931
945
932
946
if ( type === 'container' ) {
933
- return { kind : 'container' }
947
+ return {
948
+ kind : 'container' ,
949
+ nonExhaustive : nonExhaustive
950
+ }
934
951
}
935
952
936
953
assert ( jsDoc , type === 'internal' , `Bad variant type: ${ type } ` )
@@ -940,6 +957,7 @@ export function parseVariantsTag (jsDoc: JSDoc[]): model.Variants | undefined {
940
957
941
958
return {
942
959
kind : 'internal_tag' ,
960
+ nonExhaustive : nonExhaustive ,
943
961
tag : pairs . tag ,
944
962
defaultTag : pairs . default
945
963
}
@@ -972,13 +990,16 @@ export function parseCommaSeparated (value: string): string[] {
972
990
973
991
/**
974
992
* Parses an array of "key=value" pairs and validate key names. Values can optionally be enclosed with single
975
- * or double quotes.
993
+ * or double quotes. If there is only a key with no value (no '=') the value is set to 'true'
976
994
*/
977
995
export function parseKeyValues ( node : Node | Node [ ] , pairs : string [ ] , ...validKeys : string [ ] ) : Record < string , string > {
978
996
const result = { }
979
997
pairs . forEach ( item => {
980
998
const kv = item . split ( '=' )
981
- assert ( node , kv . length === 2 , 'Malformed key/value list' )
999
+ assert ( node , kv . length <= 2 , 'Malformed key/value list' )
1000
+ if ( kv . length === 1 ) {
1001
+ kv . push ( 'true' )
1002
+ }
982
1003
assert ( node , validKeys . includes ( kv [ 0 ] ) , `Unknown key '${ kv [ 0 ] } '` )
983
1004
result [ kv [ 0 ] ] = kv [ 1 ] . replace ( / [ " ' ] / g, '' )
984
1005
} )
0 commit comments