@@ -6,6 +6,9 @@ import { parseHtmlx } from './htmlxparser';
66import { convertHtmlxToJsx } from './htmlxtojsx' ;
77import { Node } from 'estree-walker' ;
88import * as ts from 'typescript' ;
9+ import { findExortKeyword } from './utils/tsAst' ;
10+ import { ExportedNames , InstanceScriptProcessResult , CreateRenderFunctionPara } from './interfaces' ;
11+ import { createRenderFunctionGetterStr , createClassGetters } from './nodes/exportgetters' ;
912
1013function AttributeValueAsJsExpression ( htmlx : string , attr : Node ) : string {
1114 if ( attr . value . length == 0 ) return "''" ; //wut?
@@ -364,20 +367,6 @@ function processSvelteTemplate(str: MagicString): TemplateProcessResult {
364367 } ;
365368}
366369
367- type ExportedNames = Map <
368- string ,
369- {
370- type ?: string ;
371- identifierText ?: string ;
372- required ?: boolean ;
373- }
374- > ;
375-
376- type InstanceScriptProcessResult = {
377- exportedNames : ExportedNames ;
378- uses$$props : boolean ;
379- uses$$restProps : boolean ;
380- } ;
381370
382371function processInstanceScriptContent ( str : MagicString , script : Node ) : InstanceScriptProcessResult {
383372 const htmlx = str . original ;
@@ -391,6 +380,7 @@ function processInstanceScriptContent(str: MagicString, script: Node): InstanceS
391380 ) ;
392381 const astOffset = script . content . start ;
393382 const exportedNames : ExportedNames = new Map ( ) ;
383+ const getters = new Set < string > ( ) ;
394384
395385 const implicitTopLevelNames : Map < string , number > = new Map ( ) ;
396386 let uses$$props = false ;
@@ -431,6 +421,12 @@ function processInstanceScriptContent(str: MagicString, script: Node): InstanceS
431421 exportedNames . set ( name . text , { } ) ;
432422 }
433423 } ;
424+ const addGetter = ( node : ts . Identifier ) => {
425+ if ( ! node ) {
426+ return ;
427+ }
428+ getters . add ( node . text ) ;
429+ } ;
434430
435431 const removeExport = ( start : number , end : number ) => {
436432 const exportStart = str . original . indexOf ( 'export' , start + astOffset ) ;
@@ -439,10 +435,6 @@ function processInstanceScriptContent(str: MagicString, script: Node): InstanceS
439435 } ;
440436
441437 const propTypeAssertToUserDefined = ( node : ts . VariableDeclarationList ) => {
442- if ( node . flags !== ts . NodeFlags . Let ) {
443- return ;
444- }
445-
446438 const hasInitializers = node . declarations . filter ( ( declaration ) => declaration . initializer ) ;
447439 const handleTypeAssertion = ( declaration : ts . VariableDeclaration ) => {
448440 const identifier = declaration . name ;
@@ -669,31 +661,46 @@ function processInstanceScriptContent(str: MagicString, script: Node): InstanceS
669661 const onLeaveCallbacks : onLeaveCallback [ ] = [ ] ;
670662
671663 if ( ts . isVariableStatement ( node ) ) {
672- const exportModifier = node . modifiers
673- ? node . modifiers . find ( ( x ) => x . kind == ts . SyntaxKind . ExportKeyword )
674- : null ;
664+ const exportModifier = findExortKeyword ( node ) ;
675665 if ( exportModifier ) {
676- handleExportedVariableDeclarationList ( node . declarationList ) ;
677- propTypeAssertToUserDefined ( node . declarationList ) ;
666+ const isLet = node . declarationList . flags === ts . NodeFlags . Let ;
667+ const isConst = node . declarationList . flags === ts . NodeFlags . Const ;
668+
669+ if ( isLet ) {
670+ handleExportedVariableDeclarationList ( node . declarationList ) ;
671+ propTypeAssertToUserDefined ( node . declarationList ) ;
672+ } else if ( isConst ) {
673+ node . declarationList . forEachChild ( ( n ) => {
674+ if ( ts . isVariableDeclaration ( n ) && ts . isIdentifier ( n . name ) ) {
675+ addGetter ( n . name ) ;
676+ }
677+ } ) ;
678+ }
678679 removeExport ( exportModifier . getStart ( ) , exportModifier . end ) ;
679680 }
680681 }
681682
682683 if ( ts . isFunctionDeclaration ( node ) ) {
683684 if ( node . modifiers ) {
684- const exportModifier = node . modifiers . find (
685- ( x ) => x . kind == ts . SyntaxKind . ExportKeyword ,
686- ) ;
685+ const exportModifier = findExortKeyword ( node ) ;
687686 if ( exportModifier ) {
688- addExport ( node . name ) ;
689687 removeExport ( exportModifier . getStart ( ) , exportModifier . end ) ;
688+ addGetter ( node . name ) ;
690689 }
691690 }
692691
693692 pushScope ( ) ;
694693 onLeaveCallbacks . push ( ( ) => popScope ( ) ) ;
695694 }
696695
696+ if ( ts . isClassDeclaration ( node ) ) {
697+ const exportModifier = findExortKeyword ( node ) ;
698+ if ( exportModifier ) {
699+ removeExport ( exportModifier . getStart ( ) , exportModifier . end ) ;
700+ addGetter ( node . name ) ;
701+ }
702+ }
703+
697704 if ( ts . isBlock ( node ) ) {
698705 pushScope ( ) ;
699706 onLeaveCallbacks . push ( ( ) => popScope ( ) ) ;
@@ -803,6 +810,7 @@ function processInstanceScriptContent(str: MagicString, script: Node): InstanceS
803810 exportedNames,
804811 uses$$props,
805812 uses$$restProps,
813+ getters,
806814 } ;
807815}
808816
@@ -825,6 +833,7 @@ function addComponentExport(
825833 uses$$propsOr$$restProps : boolean ,
826834 strictMode : boolean ,
827835 isTsFile : boolean ,
836+ getters : Set < string > ,
828837 /** A named export allows for TSDoc-compatible docstrings */
829838 className ?: string ,
830839 componentDocumentation ?: string | null ,
@@ -841,10 +850,12 @@ function addComponentExport(
841850
842851 const doc = formatComponentDocumentation ( componentDocumentation ) ;
843852
844- // eslint-disable-next-line max-len
845- const statement = `\n\n${ doc } export default class ${
846- className ? `${ className } ` : ''
847- } {\n $$prop_def = ${ propDef } \n $$slot_def = render().slots\n}`;
853+ const statement =
854+ `\n\n${ doc } export default class ${
855+ className ? `${ className } ` : ''
856+ } {\n $$prop_def = ${ propDef } \n $$slot_def = render().slots` +
857+ createClassGetters ( getters ) +
858+ '\n}' ;
848859
849860 str . append ( statement ) ;
850861}
@@ -899,15 +910,16 @@ function processModuleScriptTag(str: MagicString, script: Node) {
899910 str . overwrite ( scriptEndTagStart , script . end , ';<>' ) ;
900911}
901912
902- function createRenderFunction (
903- str : MagicString ,
904- scriptTag : Node ,
905- scriptDestination : number ,
906- slots : Map < string , Map < string , string > > ,
907- exportedNames : ExportedNames ,
908- uses$$props : boolean ,
909- uses$$restProps : boolean ,
910- ) {
913+ function createRenderFunction ( {
914+ str,
915+ scriptTag,
916+ scriptDestination,
917+ slots,
918+ getters,
919+ exportedNames,
920+ uses$$props,
921+ uses$$restProps
922+ } : CreateRenderFunctionPara ) {
911923 const htmlx = str . original ;
912924 let propsDecl = '' ;
913925
@@ -946,7 +958,7 @@ function createRenderFunction(
946958
947959 const returnString = `\nreturn { props: ${ createPropsStr (
948960 exportedNames ,
949- ) } , slots: ${ slotsAsDef } }}`;
961+ ) } , slots: ${ slotsAsDef } , getters: ${ createRenderFunctionGetterStr ( getters ) } }}`;
950962 str . append ( returnString ) ;
951963}
952964
@@ -1008,27 +1020,30 @@ export function svelte2tsx(svelte: string, options?: { filename?: string; strict
10081020
10091021 //move the instance script and process the content
10101022 let exportedNames : ExportedNames = new Map ( ) ;
1023+ let getters = new Set < string > ( ) ;
10111024 if ( scriptTag ) {
10121025 //ensure it is between the module script and the rest of the template (the variables need to be declared before the jsx template)
10131026 if ( scriptTag . start != instanceScriptTarget ) {
10141027 str . move ( scriptTag . start , scriptTag . end , instanceScriptTarget ) ;
10151028 }
10161029 const res = processInstanceScriptContent ( str , scriptTag ) ;
1017- exportedNames = res . exportedNames ;
10181030 uses$$props = uses$$props || res . uses$$props ;
10191031 uses$$restProps = uses$$restProps || res . uses$$restProps ;
1032+
1033+ ( { exportedNames, getters } = res ) ;
10201034 }
10211035
10221036 //wrap the script tag and template content in a function returning the slot and exports
1023- createRenderFunction (
1037+ createRenderFunction ( {
10241038 str,
10251039 scriptTag,
1026- instanceScriptTarget ,
1040+ scriptDestination : instanceScriptTarget ,
10271041 slots,
1042+ getters,
10281043 exportedNames,
10291044 uses$$props,
10301045 uses$$restProps,
1031- ) ;
1046+ } ) ;
10321047
10331048 // we need to process the module script after the instance script has moved otherwise we get warnings about moving edited items
10341049 if ( moduleScriptTag ) {
@@ -1042,6 +1057,7 @@ export function svelte2tsx(svelte: string, options?: { filename?: string; strict
10421057 uses$$props || uses$$restProps ,
10431058 ! ! options ?. strictMode ,
10441059 isTsFile ( scriptTag , moduleScriptTag ) ,
1060+ getters ,
10451061 className ,
10461062 componentDocumentation ,
10471063 ) ;
0 commit comments