@@ -291,56 +291,31 @@ function baseCreate(
291291 . map ( prop => {
292292 const {
293293 resolveNestedProperties,
294- } = createSchemaResolvers ( ts , typeChecker , language , symbolNode , checkerOptions ) ;
294+ } = createSchemaResolvers ( ts , typeChecker , printer , language , symbolNode , checkerOptions ) ;
295295
296296 return resolveNestedProperties ( prop ) ;
297297 } )
298298 . filter ( prop => ! vnodeEventRegex . test ( prop . name ) && ! eventProps . has ( prop . name ) ) ;
299299 }
300300
301- // fill defaults
301+ // fill <script setup> defaults
302302 const sourceScript = language . scripts . get ( componentPath ) ;
303- const sourceFile = program . getSourceFile ( componentPath ) ;
304- const scriptRanges = sourceFile ? getScriptRanges ( sourceFile ) : undefined ;
305303 const vueFile = sourceScript ?. generated ?. root ;
306- const defaults = sourceFile && scriptRanges
307- ? readDefaultsFromScript (
304+ const virtualCode = vueFile ? getVirtualCode ( componentPath ) : undefined ;
305+ const scriptSetupRanges = virtualCode ? getScriptSetupRanges ( virtualCode ) : undefined ;
306+ const defaults : Map < string , string > = virtualCode ?. sfc . scriptSetup && scriptSetupRanges
307+ ? collectPropDefaultsFromScriptSetup (
308308 ts ,
309309 printer ,
310- sourceFile ,
311- scriptRanges ,
312- exportName ,
310+ virtualCode . sfc . scriptSetup . ast ,
311+ scriptSetupRanges ,
313312 )
314- : { } ;
315- const virtualCode = vueFile ? getVirtualCode ( componentPath ) : undefined ;
316- const scriptSetupRanges = virtualCode ? getScriptSetupRanges ( virtualCode ) : undefined ;
317-
318- if ( virtualCode ?. sfc . scriptSetup && scriptSetupRanges ) {
319- Object . assign (
320- defaults ,
321- readDefaultsFromScriptSetup (
322- ts ,
323- printer ,
324- virtualCode . sfc . scriptSetup . ast ,
325- scriptSetupRanges ,
326- ) ,
327- ) ;
328- }
313+ : new Map ( ) ;
329314
330- for (
331- const [ propName , defaultExp ] of Object . entries ( defaults )
332- ) {
315+ for ( const [ propName , defaultExp ] of defaults ) {
333316 const prop = result . find ( p => p . name === propName ) ;
334317 if ( prop ) {
335- prop . default = defaultExp . default ;
336-
337- if ( defaultExp . required !== undefined ) {
338- prop . required = defaultExp . required ;
339- }
340-
341- if ( prop . default !== undefined ) {
342- prop . required = false ; // props with default are always optional
343- }
318+ prop . default ??= defaultExp ;
344319 }
345320 }
346321
@@ -356,7 +331,7 @@ function baseCreate(
356331 return calls . map ( call => {
357332 const {
358333 resolveEventSignature,
359- } = createSchemaResolvers ( ts , typeChecker , language , symbolNode , checkerOptions ) ;
334+ } = createSchemaResolvers ( ts , typeChecker , printer , language , symbolNode , checkerOptions ) ;
360335
361336 return resolveEventSignature ( call ) ;
362337 } ) . filter ( event => event . name ) ;
@@ -374,7 +349,7 @@ function baseCreate(
374349 return properties . map ( prop => {
375350 const {
376351 resolveSlotProperties,
377- } = createSchemaResolvers ( ts , typeChecker , language , symbolNode , checkerOptions ) ;
352+ } = createSchemaResolvers ( ts , typeChecker , printer , language , symbolNode , checkerOptions ) ;
378353
379354 return resolveSlotProperties ( prop ) ;
380355 } ) ;
@@ -402,7 +377,7 @@ function baseCreate(
402377 return properties . map ( prop => {
403378 const {
404379 resolveExposedProperties,
405- } = createSchemaResolvers ( ts , typeChecker , language , symbolNode , checkerOptions ) ;
380+ } = createSchemaResolvers ( ts , typeChecker , printer , language , symbolNode , checkerOptions ) ;
406381
407382 return resolveExposedProperties ( prop ) ;
408383 } ) ;
@@ -458,6 +433,7 @@ function baseCreate(
458433function createSchemaResolvers (
459434 ts : typeof import ( 'typescript' ) ,
460435 typeChecker : ts . TypeChecker ,
436+ printer : ts . Printer ,
461437 language : core . Language < string > ,
462438 symbolNode : ts . Expression ,
463439 { rawType, schema : options , noDeclarations } : MetaCheckerOptions ,
@@ -503,30 +479,49 @@ function createSchemaResolvers(
503479 } ) ) ;
504480 }
505481
506- function resolveNestedProperties ( prop : ts . Symbol ) : PropertyMeta {
507- const subtype = typeChecker . getTypeOfSymbolAtLocation ( prop , symbolNode ) ;
482+ function resolveNestedProperties ( propSymbol : ts . Symbol ) : PropertyMeta {
483+ const subtype = typeChecker . getTypeOfSymbolAtLocation ( propSymbol , symbolNode ) ;
508484 let schema : PropertyMetaSchema | undefined ;
509485 let declarations : Declaration [ ] | undefined ;
510486 let global = false ;
487+ let _default : string | undefined ;
488+ let required = ! ( propSymbol . flags & ts . SymbolFlags . Optional ) ;
511489
512- for ( const decl of prop . declarations ?? [ ] ) {
490+ for ( const decl of propSymbol . declarations ?? [ ] ) {
513491 if (
514492 decl . getSourceFile ( ) !== symbolNode . getSourceFile ( )
515493 && isPublicProp ( decl )
516494 ) {
517495 global = true ;
518496 }
497+ if ( ts . isPropertyAssignment ( decl ) && ts . isObjectLiteralExpression ( decl . initializer ) ) {
498+ for ( const option of decl . initializer . properties ) {
499+ if ( ts . isPropertyAssignment ( option ) ) {
500+ const key = option . name . getText ( ) ;
501+ if ( key === 'default' ) {
502+ const defaultExp = resolveDefaultOptionExpression ( ts , option . initializer ) ;
503+ _default = printer . printNode ( ts . EmitHint . Expression , defaultExp , decl . getSourceFile ( ) ) ;
504+ }
505+ else if ( key === 'required' ) {
506+ if ( option . initializer . getText ( ) === 'true' ) {
507+ required = true ;
508+ }
509+ }
510+ }
511+ }
512+ }
519513 }
520514
521515 return {
522- name : prop . getEscapedName ( ) . toString ( ) ,
516+ name : propSymbol . getEscapedName ( ) . toString ( ) ,
523517 global,
524- description : ts . displayPartsToString ( prop . getDocumentationComment ( typeChecker ) ) ,
525- tags : getJsDocTags ( prop ) ,
526- required : ! ( prop . flags & ts . SymbolFlags . Optional ) ,
518+ default : _default ,
519+ description : ts . displayPartsToString ( propSymbol . getDocumentationComment ( typeChecker ) ) ,
520+ tags : getJsDocTags ( propSymbol ) ,
521+ required,
527522 type : getFullyQualifiedName ( subtype ) ,
528523 get declarations ( ) {
529- return declarations ??= getDeclarations ( prop . declarations ?? [ ] ) ;
524+ return declarations ??= getDeclarations ( propSymbol . declarations ?? [ ] ) ;
530525 } ,
531526 get schema ( ) {
532527 return schema ??= resolveSchema ( subtype ) ;
@@ -768,13 +763,13 @@ function createSchemaResolvers(
768763 } ;
769764}
770765
771- function readDefaultsFromScriptSetup (
766+ function collectPropDefaultsFromScriptSetup (
772767 ts : typeof import ( 'typescript' ) ,
773768 printer : ts . Printer ,
774769 sourceFile : ts . SourceFile ,
775770 scriptSetupRanges : core . ScriptSetupRanges ,
776771) {
777- const result : Record < string , { default ?: string } > = { } ;
772+ const result = new Map < string , string > ( ) ;
778773
779774 if ( scriptSetupRanges . withDefaults ?. arg ) {
780775 const obj = findObjectLiteralExpression ( ts , scriptSetupRanges . withDefaults . arg . node ) ;
@@ -783,28 +778,17 @@ function readDefaultsFromScriptSetup(
783778 if ( ts . isPropertyAssignment ( prop ) ) {
784779 const name = prop . name . getText ( sourceFile ) ;
785780 const expNode = resolveDefaultOptionExpression ( ts , prop . initializer ) ;
786- const expText = printer . printNode ( ts . EmitHint . Expression , expNode , sourceFile )
787- ?? expNode . getText ( sourceFile ) ;
788- result [ name ] = { default : expText } ;
781+ const expText = printer . printNode ( ts . EmitHint . Expression , expNode , sourceFile ) ;
782+ result . set ( name , expText ) ;
789783 }
790784 }
791785 }
792786 }
793- else if ( scriptSetupRanges . defineProps ?. arg ) {
794- const obj = findObjectLiteralExpression ( ts , scriptSetupRanges . defineProps . arg . node ) ;
795- if ( obj ) {
796- Object . assign (
797- result ,
798- resolvePropsOption ( ts , printer , sourceFile , obj ) ,
799- ) ;
800- }
801- }
802787 else if ( scriptSetupRanges . defineProps ?. destructured ) {
803788 for ( const [ name , initializer ] of scriptSetupRanges . defineProps . destructured ) {
804789 if ( initializer ) {
805- const expText = printer . printNode ( ts . EmitHint . Expression , initializer , sourceFile )
806- ?? initializer . getText ( sourceFile ) ;
807- result [ name ] = { default : expText } ;
790+ const expText = printer . printNode ( ts . EmitHint . Expression , initializer , sourceFile ) ;
791+ result . set ( name , expText ) ;
808792 }
809793 }
810794 }
@@ -816,7 +800,10 @@ function readDefaultsFromScriptSetup(
816800 const name = defineModel . name
817801 ? sourceFile . text . slice ( defineModel . name . start , defineModel . name . end ) . slice ( 1 , - 1 )
818802 : 'modelValue' ;
819- result [ name ] = { default : resolveModelOption ( ts , printer , sourceFile , obj ) } ;
803+ const _default = resolveModelOption ( ts , printer , sourceFile , obj ) ;
804+ if ( _default ) {
805+ result . set ( name , _default ) ;
806+ }
820807 }
821808 }
822809 }
@@ -840,64 +827,6 @@ function findObjectLiteralExpression(
840827 return result ;
841828}
842829
843- function readDefaultsFromScript (
844- ts : typeof import ( 'typescript' ) ,
845- printer : ts . Printer ,
846- sourceFile : ts . SourceFile ,
847- scriptRanges : core . ScriptRanges ,
848- exportName : string ,
849- ) {
850- const component = scriptRanges . exports [ exportName ] ;
851- if ( ! component ) {
852- return { } ;
853- }
854- const props = component ?. options ?. args . node . properties . find ( prop => prop . name ?. getText ( sourceFile ) === 'props' ) ;
855- if ( props && ts . isPropertyAssignment ( props ) ) {
856- if ( ts . isObjectLiteralExpression ( props . initializer ) ) {
857- return resolvePropsOption ( ts , printer , sourceFile , props . initializer ) ;
858- }
859- }
860- return { } ;
861- }
862-
863- function resolvePropsOption (
864- ts : typeof import ( 'typescript' ) ,
865- printer : ts . Printer ,
866- sourceFile : ts . SourceFile ,
867- props : ts . ObjectLiteralExpression ,
868- ) {
869- const result : Record < string , { default ?: string ; required ?: boolean } > = { } ;
870-
871- for ( const prop of props . properties ) {
872- if ( ts . isPropertyAssignment ( prop ) ) {
873- const name = prop . name . getText ( sourceFile ) ;
874- if ( ts . isObjectLiteralExpression ( prop . initializer ) ) {
875- const defaultProp = prop . initializer . properties . find ( p =>
876- ts . isPropertyAssignment ( p ) && p . name . getText ( sourceFile ) === 'default'
877- ) as ts . PropertyAssignment | undefined ;
878- const requiredProp = prop . initializer . properties . find ( p =>
879- ts . isPropertyAssignment ( p ) && p . name . getText ( sourceFile ) === 'required'
880- ) as ts . PropertyAssignment | undefined ;
881-
882- result [ name ] = { } ;
883-
884- if ( requiredProp ) {
885- const exp = requiredProp . initializer . getText ( sourceFile ) ;
886- result [ name ] . required = exp === 'true' ;
887- }
888- if ( defaultProp ) {
889- const expNode = resolveDefaultOptionExpression ( ts , defaultProp . initializer ) ;
890- const expText = printer . printNode ( ts . EmitHint . Expression , expNode , sourceFile )
891- ?? expNode . getText ( sourceFile ) ;
892- result [ name ] . default = expText ;
893- }
894- }
895- }
896- }
897-
898- return result ;
899- }
900-
901830function resolveModelOption (
902831 ts : typeof import ( 'typescript' ) ,
903832 printer : ts . Printer ,
0 commit comments