@@ -440,7 +440,7 @@ export function modelEnumDeclaration (declaration: EnumDeclaration): model.Enum
440
440
}
441
441
442
442
const tags = parseJsDocTags ( declaration . getJsDocs ( ) )
443
- if ( typeof tags . open_enum === 'string' ) {
443
+ if ( typeof tags . non_exhaustive === 'string' ) {
444
444
type . isOpen = true
445
445
}
446
446
@@ -647,7 +647,7 @@ export function hoistTypeAnnotations (type: model.TypeDefinition, jsDocs: JSDoc[
647
647
// We want to enforce a single jsDoc block.
648
648
assert ( jsDocs , jsDocs . length < 2 , 'Use a single multiline jsDoc block instead of multiple single line blocks' )
649
649
650
- const validTags = [ 'class_serializer' , 'doc_url' , 'doc_id' , 'behavior' , 'variants' , 'variant' , 'shortcut_property' , 'codegen_names' ]
650
+ const validTags = [ 'class_serializer' , 'doc_url' , 'doc_id' , 'behavior' , 'variants' , 'variant' , 'shortcut_property' , 'codegen_names' , 'non_exhaustive' ]
651
651
const tags = parseJsDocTags ( jsDocs )
652
652
if ( jsDocs . length === 1 ) {
653
653
const description = jsDocs [ 0 ] . getDescription ( )
@@ -665,6 +665,8 @@ export function hoistTypeAnnotations (type: model.TypeDefinition, jsDocs: JSDoc[
665
665
}
666
666
} else if ( tag === 'variants' ) {
667
667
} else if ( tag === 'variant' ) {
668
+ } else if ( tag === 'non_exhaustive' ) {
669
+ assert ( jsDocs , typeof tags . variants === 'string' , '@non_exhaustive only applies to enums and @variants' )
668
670
} else if ( tag === 'doc_url' ) {
669
671
assert ( jsDocs , isValidUrl ( value ) , '@doc_url is not a valid url' )
670
672
type . docUrl = value
@@ -954,13 +956,21 @@ export function parseVariantsTag (jsDoc: JSDoc[]): model.Variants | undefined {
954
956
return undefined
955
957
}
956
958
959
+ const nonExhaustive = ( typeof tags . non_exhaustive === 'string' ) ? true : undefined
960
+
957
961
const [ type , ...values ] = tags . variants . split ( ' ' )
958
962
if ( type === 'external' ) {
959
- return { kind : 'external_tag' }
963
+ return {
964
+ kind : 'external_tag' ,
965
+ nonExhaustive : nonExhaustive
966
+ }
960
967
}
961
968
962
969
if ( type === 'container' ) {
963
- return { kind : 'container' }
970
+ return {
971
+ kind : 'container' ,
972
+ nonExhaustive : nonExhaustive
973
+ }
964
974
}
965
975
966
976
assert ( jsDoc , type === 'internal' , `Bad variant type: ${ type } ` )
@@ -970,6 +980,7 @@ export function parseVariantsTag (jsDoc: JSDoc[]): model.Variants | undefined {
970
980
971
981
return {
972
982
kind : 'internal_tag' ,
983
+ nonExhaustive : nonExhaustive ,
973
984
tag : pairs . tag ,
974
985
defaultTag : pairs . default
975
986
}
@@ -1002,13 +1013,16 @@ export function parseCommaSeparated (value: string): string[] {
1002
1013
1003
1014
/**
1004
1015
* Parses an array of "key=value" pairs and validate key names. Values can optionally be enclosed with single
1005
- * or double quotes.
1016
+ * or double quotes. If there is only a key with no value (no '=') the value is set to 'true'
1006
1017
*/
1007
1018
export function parseKeyValues ( node : Node | Node [ ] , pairs : string [ ] , ...validKeys : string [ ] ) : Record < string , string > {
1008
1019
const result = { }
1009
1020
pairs . forEach ( item => {
1010
1021
const kv = item . split ( '=' )
1011
- assert ( node , kv . length === 2 , 'Malformed key/value list' )
1022
+ assert ( node , kv . length <= 2 , 'Malformed key/value list' )
1023
+ if ( kv . length === 1 ) {
1024
+ kv . push ( 'true' )
1025
+ }
1012
1026
assert ( node , validKeys . includes ( kv [ 0 ] ) , `Unknown key '${ kv [ 0 ] } '` )
1013
1027
result [ kv [ 0 ] ] = kv [ 1 ] . replace ( / [ " ' ] / g, '' )
1014
1028
} )
0 commit comments