@@ -29,7 +29,7 @@ import {
2929 TypeTree ,
3030 VariableDeclarator ,
3131} from '../java' ;
32- import { DelegatedYield , FunctionDeclaration , Generator , JS , JSX , NonNullAssertion , Optional , Spread } from '.' ;
32+ import { DelegatedYield , FunctionDeclaration , Generator , JS , JSX , NonNullAssertion , Optional } from '.' ;
3333import { emptyMarkers , markers , Markers , MarkersKind , ParseExceptionResult , replaceMarkerByKind } from "../markers" ;
3434import { NamedStyles } from "../style" ;
3535import { Parser , ParserInput , parserInputFile , parserInputRead , ParserOptions , Parsers , SourcePath } from "../parser" ;
@@ -1028,6 +1028,21 @@ export class JavaScriptParserVisitor {
10281028 }
10291029
10301030 visitParameter ( node : ts . ParameterDeclaration ) : J . VariableDeclarations {
1031+ let name : VariableDeclarator = produce ( this . convert < VariableDeclarator > ( node . name ) , draft => {
1032+ draft . markers = this . maybeAddOptionalMarker ( draft , node ) ;
1033+ } ) ;
1034+ if ( node . dotDotDotToken ) {
1035+ // Wrap in JS.Spread; prefix between ... and identifier stays on the inner expression
1036+ const spread : JS . Spread = {
1037+ kind : JS . Kind . Spread ,
1038+ id : randomId ( ) ,
1039+ prefix : emptySpace ,
1040+ markers : emptyMarkers ,
1041+ expression : name as Expression ,
1042+ type : this . mapType ( node )
1043+ } ;
1044+ name = spread ;
1045+ }
10311046 return {
10321047 kind : J . Kind . VariableDeclarations ,
10331048 id : randomId ( ) ,
@@ -1042,16 +1057,7 @@ export class JavaScriptParserVisitor {
10421057 id : randomId ( ) ,
10431058 prefix : node . dotDotDotToken ? this . prefix ( node . dotDotDotToken ) : this . prefix ( node . name ) ,
10441059 markers : emptyMarkers ,
1045- name : produce ( this . convert < VariableDeclarator > ( node . name ) , draft => {
1046- draft . markers = this . maybeAddOptionalMarker ( draft , node ) ;
1047- if ( node . dotDotDotToken ) {
1048- draft . markers . markers . push ( {
1049- kind : JS . Markers . Spread ,
1050- id : randomId ( ) ,
1051- prefix : this . prefix ( node . name )
1052- } satisfies Spread as Spread ) ;
1053- }
1054- } ) ,
1060+ name : name ,
10551061 dimensionsAfterName : [ ] ,
10561062 initializer : node . initializer && this . leftPadded ( this . prefix ( node . getChildAt ( node . getChildren ( ) . indexOf ( node . initializer ) - 1 ) ) , this . visit ( node . initializer ) ) ,
10571063 variableType : this . mapVariableType ( node )
@@ -1579,14 +1585,16 @@ export class JavaScriptParserVisitor {
15791585 } ) ;
15801586 }
15811587
1582- visitRestType ( node : ts . RestTypeNode ) : Expression {
1583- return produce ( this . convert < Expression > ( node . type ) , draft => {
1584- draft . markers . markers . push ( {
1585- kind : JS . Markers . Spread ,
1586- id : randomId ( ) ,
1587- prefix : this . prefix ( node )
1588- } satisfies Spread as Spread ) ;
1589- } ) ;
1588+ visitRestType ( node : ts . RestTypeNode ) : JS . Spread {
1589+ const innerExpr = this . convert < Expression > ( node . type ) ;
1590+ return {
1591+ kind : JS . Kind . Spread ,
1592+ id : randomId ( ) ,
1593+ prefix : this . prefix ( node ) ,
1594+ markers : emptyMarkers ,
1595+ expression : { ...innerExpr , prefix : emptySpace } ,
1596+ type : this . mapType ( node )
1597+ } ;
15901598 }
15911599
15921600 visitUnionType ( node : ts . UnionTypeNode ) : JS . Union {
@@ -1818,6 +1826,22 @@ export class JavaScriptParserVisitor {
18181826 // and this would potentially just trip up flow analyses. The names exist purely for documentation purposes,
18191827 // they has no semantics. See https://stackoverflow.com/questions/63629315/what-are-named-or-labeled-tuples-in-typescript.
18201828 visitNamedTupleMember ( node : ts . NamedTupleMember ) : J . VariableDeclarations {
1829+ let name : VariableDeclarator = produce ( this . convert < J . Identifier > ( node . name ) , draft => {
1830+ draft . markers = this . maybeAddOptionalMarker ( draft , node ) ;
1831+ } ) ;
1832+ if ( node . dotDotDotToken ) {
1833+ // Wrap in JS.Spread; use emptySpace since the whitespace belongs
1834+ // to VariableDeclarations.prefix, not to the spread itself
1835+ const spread : JS . Spread = {
1836+ kind : JS . Kind . Spread ,
1837+ id : randomId ( ) ,
1838+ prefix : emptySpace ,
1839+ markers : emptyMarkers ,
1840+ expression : name as Expression ,
1841+ type : this . mapType ( node )
1842+ } ;
1843+ name = spread ;
1844+ }
18211845 return {
18221846 kind : J . Kind . VariableDeclarations ,
18231847 id : randomId ( ) ,
@@ -1832,16 +1856,7 @@ export class JavaScriptParserVisitor {
18321856 id : randomId ( ) ,
18331857 prefix : emptySpace ,
18341858 markers : emptyMarkers ,
1835- name : produce ( this . convert < J . Identifier > ( node . name ) , draft => {
1836- draft . markers = this . maybeAddOptionalMarker ( draft , node ) ;
1837- if ( node . dotDotDotToken ) {
1838- draft . markers . markers . push ( {
1839- kind : JS . Markers . Spread ,
1840- id : randomId ( ) ,
1841- prefix : this . prefix ( node . dotDotDotToken )
1842- } satisfies Spread as Spread ) ;
1843- }
1844- } ) ,
1859+ name : name ,
18451860 dimensionsAfterName : [ ] ,
18461861 variableType : this . mapVariableType ( node ) ,
18471862 } ,
@@ -1937,21 +1952,28 @@ export class JavaScriptParserVisitor {
19371952 }
19381953
19391954 visitBindingElement ( node : ts . BindingElement ) : JS . BindingElement {
1955+ // Capture prefix before converting name, as convert may consume whitespace
1956+ const elementPrefix = this . prefix ( node ) ;
1957+ let name : Expression = this . convert < Expression > ( node . name ) ;
1958+ if ( node . dotDotDotToken ) {
1959+ // Wrap in JS.Spread; use emptySpace for prefix since the whitespace
1960+ // belongs to BindingElement.prefix, not to the spread itself
1961+ name = {
1962+ kind : JS . Kind . Spread ,
1963+ id : randomId ( ) ,
1964+ prefix : emptySpace ,
1965+ markers : emptyMarkers ,
1966+ expression : name ,
1967+ type : this . mapType ( node )
1968+ } satisfies JS . Spread as Expression ;
1969+ }
19401970 return {
19411971 kind : JS . Kind . BindingElement ,
19421972 id : randomId ( ) ,
1943- prefix : this . prefix ( node ) ,
1973+ prefix : elementPrefix ,
19441974 markers : emptyMarkers ,
19451975 propertyName : node . propertyName && this . rightPadded ( this . convert < J . Identifier > ( node . propertyName ) , this . suffix ( node . propertyName ) ) ,
1946- name : produce ( this . convert < Expression > ( node . name ) , draft => {
1947- if ( node . dotDotDotToken ) {
1948- draft . markers . markers . push ( {
1949- kind : JS . Markers . Spread ,
1950- id : randomId ( ) ,
1951- prefix : this . prefix ( node . dotDotDotToken )
1952- } satisfies Spread as Spread ) ;
1953- }
1954- } ) ,
1976+ name : name ,
19551977 initializer : node . initializer && this . leftPadded ( this . prefix ( this . findChildNode ( node , ts . SyntaxKind . EqualsToken ) ! ) , this . convert < Expression > ( node . initializer ) ) ,
19561978 variableType : this . mapVariableType ( node )
19571979 } ;
@@ -2622,14 +2644,15 @@ export class JavaScriptParserVisitor {
26222644 } ;
26232645 }
26242646
2625- visitSpreadElement ( node : ts . SpreadElement ) : Expression {
2626- return produce ( this . convert < Expression > ( node . expression ) , draft => {
2627- draft . markers . markers . push ( {
2628- kind : JS . Markers . Spread ,
2629- id : randomId ( ) ,
2630- prefix : this . prefix ( node )
2631- } satisfies Spread as Spread ) ;
2632- } ) ;
2647+ visitSpreadElement ( node : ts . SpreadElement ) : JS . Spread {
2648+ return {
2649+ kind : JS . Kind . Spread ,
2650+ id : randomId ( ) ,
2651+ prefix : this . prefix ( node ) ,
2652+ markers : emptyMarkers ,
2653+ expression : this . convert ( node . expression ) ,
2654+ type : this . mapType ( node )
2655+ } ;
26332656 }
26342657
26352658 visitClassExpression ( node : ts . ClassExpression ) : JS . StatementExpression {
@@ -3903,13 +3926,16 @@ export class JavaScriptParserVisitor {
39033926 let expr : Expression ;
39043927 if ( node . expression ) {
39053928 if ( node . dotDotDotToken ) {
3906- expr = produce ( this . convert < Expression > ( node . expression ) , draft => {
3907- draft . markers . markers . push ( {
3908- kind : JS . Markers . Spread ,
3909- id : randomId ( ) ,
3910- prefix : this . prefix ( node . dotDotDotToken ! )
3911- } satisfies Spread as Spread ) ;
3912- } ) ;
3929+ // Wrap in JS.Spread
3930+ const innerExpr = this . convert < Expression > ( node . expression ) ;
3931+ expr = {
3932+ kind : JS . Kind . Spread ,
3933+ id : randomId ( ) ,
3934+ prefix : this . prefix ( node . dotDotDotToken ! ) ,
3935+ markers : emptyMarkers ,
3936+ expression : innerExpr ,
3937+ type : this . mapType ( node . expression )
3938+ } satisfies JS . Spread as Expression ;
39133939 } else {
39143940 expr = this . convert < Expression > ( node . expression ) ;
39153941 }
@@ -4086,23 +4112,14 @@ export class JavaScriptParserVisitor {
40864112 } ;
40874113 }
40884114
4089- visitSpreadAssignment ( node : ts . SpreadAssignment ) : JS . PropertyAssignment {
4115+ visitSpreadAssignment ( node : ts . SpreadAssignment ) : JS . Spread {
40904116 return {
4091- kind : JS . Kind . PropertyAssignment ,
4117+ kind : JS . Kind . Spread ,
40924118 id : randomId ( ) ,
40934119 prefix : this . prefix ( node ) ,
40944120 markers : emptyMarkers ,
4095- name : this . rightPadded (
4096- produce ( this . convert < Expression > ( node . expression ) , draft => {
4097- draft . markers . markers . push ( {
4098- kind : JS . Markers . Spread ,
4099- id : randomId ( ) ,
4100- prefix : this . prefix ( node )
4101- } satisfies Spread as Spread ) ;
4102- } ) ,
4103- this . suffix ( node . expression )
4104- ) ,
4105- assigmentToken : JS . PropertyAssignment . Token . Empty ,
4121+ expression : this . convert ( node . expression ) ,
4122+ type : this . mapType ( node )
41064123 } ;
41074124 }
41084125
0 commit comments