33module . exports = toEstree
44
55var commas = require ( 'comma-separated-tokens' )
6+ var attachComments = require ( 'estree-util-attach-comments' )
67var whitespace = require ( 'hast-util-whitespace' )
78var find = require ( 'property-information/find' )
89var hastToReact = require ( 'property-information/hast-to-react.json' )
@@ -31,6 +32,7 @@ var handlers = {
3132function toEstree ( tree , options ) {
3233 var context = {
3334 schema : options && options . space === 'svg' ? svg : html ,
35+ comments : [ ] ,
3436 esm : [ ] ,
3537 handle : zwitch ( 'type' , {
3638 invalid : invalid ,
@@ -49,7 +51,12 @@ function toEstree(tree, options) {
4951 body . push ( create ( tree , { type : 'ExpressionStatement' , expression : result } ) )
5052 }
5153
52- return create ( tree , { type : 'Program' , body : body , sourceType : 'module' } )
54+ return create ( tree , {
55+ type : 'Program' ,
56+ body : body ,
57+ sourceType : 'module' ,
58+ comments : context . comments
59+ } )
5360}
5461
5562function invalid ( value ) {
@@ -62,22 +69,16 @@ function unknown(node) {
6269
6370function ignore ( ) { }
6471
65- function comment ( node ) {
72+ function comment ( node , context ) {
73+ var esnode = create ( node , { type : 'Block' , value : node . value } )
74+
75+ context . comments . push ( esnode )
76+
6677 return create ( node , {
6778 type : 'JSXExpressionContainer' ,
6879 expression : create ( node , {
6980 type : 'JSXEmptyExpression' ,
70- // Babel.
71- innerComments : [ create ( node , { type : 'CommentBlock' , value : node . value } ) ] ,
72- // Recast.
73- comments : [
74- create ( node , {
75- type : 'Block' ,
76- value : node . value ,
77- leading : false ,
78- trailing : true
79- } )
80- ]
81+ comments : [ Object . assign ( { } , esnode , { leading : false , trailing : true } ) ]
8182 } )
8283 } )
8384}
@@ -185,21 +186,28 @@ function element(node, context) {
185186}
186187
187188function mdxjsEsm ( node , context ) {
188- push . apply (
189- context . esm ,
190- ( node . data && node . data . estree && node . data . estree . body ) || [ ]
191- )
189+ var estree = node . data && node . data . estree
190+
191+ if ( estree ) {
192+ push . apply ( context . comments , estree . comments )
193+ attachComments ( estree , estree . comments )
194+ push . apply ( context . esm , estree . body )
195+ }
192196}
193197
194- function mdxExpression ( node ) {
198+ function mdxExpression ( node , context ) {
199+ var estree = node . data && node . data . estree
200+ var expression
201+
202+ if ( estree ) {
203+ push . apply ( context . comments , estree . comments )
204+ attachComments ( estree , estree . comments )
205+ expression = estree . body [ 0 ] && estree . body [ 0 ] . expression
206+ }
207+
195208 return create ( node , {
196209 type : 'JSXExpressionContainer' ,
197- expression :
198- ( node . data &&
199- node . data . estree &&
200- node . data . estree . body [ 0 ] &&
201- node . data . estree . body [ 0 ] . expression ) ||
202- create ( node , { type : 'JSXEmptyExpression' } )
210+ expression : expression || create ( node , { type : 'JSXEmptyExpression' } )
203211 } )
204212}
205213
@@ -212,6 +220,8 @@ function mdxJsxElement(node, context) {
212220 var index = - 1
213221 var children
214222 var attr
223+ var value
224+ var estree
215225
216226 if (
217227 node . name &&
@@ -226,49 +236,68 @@ function mdxJsxElement(node, context) {
226236
227237 while ( ++ index < attrs . length ) {
228238 attr = attrs [ index ]
239+ value = attr . value
229240
230241 if ( attr . type === 'mdxJsxAttribute' ) {
242+ if ( value == null ) {
243+ // Empty.
244+ }
245+ // MDXJsxAttributeValueExpression.
246+ else if ( typeof value === 'object' ) {
247+ estree = value . data && value . data . estree
248+ value = null
249+
250+ if ( estree ) {
251+ push . apply ( context . comments , estree . comments )
252+ attachComments ( estree , estree . comments )
253+ value = estree . body [ 0 ] && estree . body [ 0 ] . expression
254+ }
255+
256+ // To do: `node` is wrong.
257+ value = create ( node , {
258+ type : 'JSXExpressionContainer' ,
259+ expression : value || create ( null , { type : 'JSXEmptyExpression' } )
260+ } )
261+ }
262+ // Anything else.
263+ else {
264+ // To do: use `value`?
265+ value = create ( null , {
266+ type : 'Literal' ,
267+ value : String ( value ) ,
268+ raw : JSON . stringify ( String ( value ) )
269+ } )
270+ }
271+
231272 attributes . push (
232273 create ( null , {
233274 type : 'JSXAttribute' ,
234275 name : createJsxName ( attr . name ) ,
235- value :
236- attr . value == null
237- ? null
238- : typeof attr . value === 'object'
239- ? // MDXJsxAttributeValueExpression.
240- create ( node , {
241- type : 'JSXExpressionContainer' ,
242- expression :
243- ( attr . value . data &&
244- attr . value . data . estree &&
245- attr . value . data . estree . body [ 0 ] &&
246- attr . value . data . estree . body [ 0 ] . expression ) ||
247- create ( null , { type : 'JSXEmptyExpression' } )
248- } )
249- : // Anything else.
250- create ( null , {
251- type : 'Literal' ,
252- value : String ( attr . value ) ,
253- raw : JSON . stringify ( String ( attr . value ) )
254- } )
276+ value : value
255277 } )
256278 )
257279 }
258280 // MDXJsxExpressionAttribute.
259281 else {
282+ estree = attr . data && attr . data . estree
283+ value = null
284+
285+ if ( estree ) {
286+ push . apply ( context . comments , estree . comments )
287+ attachComments ( estree , estree . comments )
288+ value =
289+ estree . body [ 0 ] &&
290+ estree . body [ 0 ] . expression &&
291+ estree . body [ 0 ] . expression . properties &&
292+ estree . body [ 0 ] . expression . properties [ 0 ] &&
293+ estree . body [ 0 ] . expression . properties [ 0 ] . argument
294+ }
295+
260296 attributes . push (
261297 create ( null , {
262298 type : 'JSXSpreadAttribute' ,
263299 argument :
264- ( attr . data &&
265- attr . data . estree &&
266- attr . data . estree . body [ 0 ] &&
267- attr . data . estree . body [ 0 ] . expression &&
268- attr . data . estree . body [ 0 ] . expression . properties &&
269- attr . data . estree . body [ 0 ] . expression . properties [ 0 ] &&
270- attr . data . estree . body [ 0 ] . expression . properties [ 0 ] . argument ) ||
271- create ( null , { type : 'ObjectExpression' , properties : { } } )
300+ value || create ( null , { type : 'ObjectExpression' , properties : { } } )
272301 } )
273302 )
274303 }
@@ -396,17 +425,19 @@ function all(parent, context) {
396425 return results
397426}
398427
399- function create ( hast , esnode ) {
428+ function create ( hast , esnode , fromStart , fromEnd ) {
400429 var p = position ( hast )
430+ var left = fromStart || 0
431+ var right = fromEnd || 0
401432
402433 if ( p . start . line ) {
403- esnode . start = p . start . offset
404- esnode . end = p . end . offset
434+ esnode . start = p . start . offset + left
435+ esnode . end = p . end . offset - right
405436 esnode . loc = {
406- start : { line : p . start . line , column : p . start . column - 1 } ,
407- end : { line : p . end . line , column : p . end . column - 1 }
437+ start : { line : p . start . line , column : p . start . column - 1 + left } ,
438+ end : { line : p . end . line , column : p . end . column - 1 - right }
408439 }
409- esnode . range = [ p . start . offset , p . end . offset ]
440+ esnode . range = [ p . start . offset + left , p . end . offset - right ]
410441 }
411442
412443 return esnode
0 commit comments