11import { isGloballyAllowed , isString } from '@vue-vapor/shared'
22import {
33 type AttributeNode ,
4+ type DirectiveNode ,
45 type ElementNode ,
6+ ElementTypes ,
7+ Namespaces ,
58 NodeTypes ,
69 type SimpleExpressionNode ,
10+ type TextNode ,
711 findDir as _findDir ,
812 findProp as _findProp ,
913 createSimpleExpression ,
@@ -19,6 +23,7 @@ import type {
1923 BigIntLiteral ,
2024 CallExpression ,
2125 Expression ,
26+ JSXAttribute ,
2227 JSXElement ,
2328 Node ,
2429 NumericLiteral ,
@@ -81,7 +86,7 @@ export function getLiteralExpressionValue(
8186export function resolveExpression (
8287 node : Node | undefined | null ,
8388 context : TransformContext ,
84- ) {
89+ ) : SimpleExpressionNode {
8590 const isStatic =
8691 ! ! node &&
8792 ( node . type === 'StringLiteral' ||
@@ -154,6 +159,99 @@ export function resolveLocation(
154159 }
155160}
156161
162+ export function resolveValue (
163+ value : JSXAttribute [ 'value' ] ,
164+ context : TransformContext ,
165+ ) : TextNode | undefined {
166+ return value
167+ ? {
168+ type : NodeTypes . TEXT ,
169+ content :
170+ value . type === 'StringLiteral'
171+ ? value . value
172+ : value . type === 'JSXExpressionContainer'
173+ ? context . ir . source . slice (
174+ value . expression . start ! ,
175+ value . expression . end ! ,
176+ )
177+ : '' ,
178+ loc : resolveLocation ( value . loc , context ) ,
179+ }
180+ : undefined
181+ }
182+
183+ export function resolveNode (
184+ node : JSXElement ,
185+ context : TransformContext ,
186+ ) : ElementNode {
187+ const tag =
188+ node . openingElement . name . type === 'JSXIdentifier'
189+ ? node . openingElement . name . name
190+ : ''
191+ const loc = resolveLocation ( node . loc , context )
192+ const tagType = isComponentNode ( node )
193+ ? ElementTypes . COMPONENT
194+ : ElementTypes . ELEMENT
195+ const props = node . openingElement . attributes . reduce (
196+ ( result , attr ) => {
197+ if ( attr . type === 'JSXAttribute' ) {
198+ if ( tagType === ElementTypes . COMPONENT ) {
199+ result . push ( resolveDirectiveNode ( attr , context ) )
200+ } else {
201+ result . push ( {
202+ type : NodeTypes . ATTRIBUTE ,
203+ name : `${ attr . name . name } ` ,
204+ nameLoc : resolveLocation ( attr . name . loc , context ) ,
205+ value : resolveValue ( attr . value , context ) ,
206+ loc : resolveLocation ( attr . loc , context ) ,
207+ } )
208+ }
209+ }
210+ return result
211+ } ,
212+ [ ] as Array < AttributeNode | DirectiveNode > ,
213+ )
214+
215+ return {
216+ type : NodeTypes . ELEMENT ,
217+ props,
218+ children : [ ] ,
219+ tag,
220+ loc,
221+ ns : Namespaces . HTML ,
222+ tagType,
223+ isSelfClosing : ! ! node . selfClosing ,
224+ codegenNode : undefined ,
225+ }
226+ }
227+
228+ export function resolveDirectiveNode (
229+ node : JSXAttribute ,
230+ context : TransformContext ,
231+ ) : VaporDirectiveNode {
232+ const { value, name } = node
233+ const nameString = name . type === 'JSXIdentifier' ? name . name : ''
234+ const argString = name . type === 'JSXNamespacedName' ? name . namespace . name : ''
235+
236+ const arg =
237+ name . type === 'JSXNamespacedName'
238+ ? resolveSimpleExpression ( argString , true , name . namespace . loc )
239+ : undefined
240+ const exp = value ? resolveExpression ( value , context ) : undefined
241+
242+ const [ tag , ...modifiers ] = argString . split ( '_' )
243+
244+ return {
245+ type : NodeTypes . DIRECTIVE ,
246+ name : nameString ,
247+ rawName : `${ name } :${ tag } ` ,
248+ exp,
249+ arg,
250+ loc : resolveLocation ( node . loc , context ) ,
251+ modifiers,
252+ }
253+ }
254+
157255export function isComponentNode ( node : Node ) : node is JSXElement {
158256 if ( node . type !== 'JSXElement' ) return false
159257
0 commit comments