mirror of https://github.com/vuejs/core.git
wip(compiler-vapor): support expressions in idMap
This commit is contained in:
parent
1ff6b136db
commit
5d88c53cd3
|
@ -1,6 +1,7 @@
|
|||
import type {
|
||||
CodegenOptions as BaseCodegenOptions,
|
||||
BaseCodegenResult,
|
||||
SimpleExpressionNode,
|
||||
} from '@vue/compiler-dom'
|
||||
import type { BlockIRNode, CoreHelper, RootIRNode, VaporHelper } from './ir'
|
||||
import { extend, remove } from '@vue/shared'
|
||||
|
@ -32,12 +33,16 @@ export class CodegenContext {
|
|||
|
||||
delegates: Set<string> = new Set<string>()
|
||||
|
||||
identifiers: Record<string, string[]> = Object.create(null)
|
||||
identifiers: Record<string, (string | SimpleExpressionNode)[]> =
|
||||
Object.create(null)
|
||||
|
||||
seenInlineHandlerNames: Record<string, number> = Object.create(null)
|
||||
|
||||
block: BlockIRNode
|
||||
withId<T>(fn: () => T, map: Record<string, string | null>): T {
|
||||
withId<T>(
|
||||
fn: () => T,
|
||||
map: Record<string, string | SimpleExpressionNode | null>,
|
||||
): T {
|
||||
const { identifiers } = this
|
||||
const ids = Object.keys(map)
|
||||
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
import { NOOP, extend, genPropsAccessExp, isGloballyAllowed } from '@vue/shared'
|
||||
import {
|
||||
NOOP,
|
||||
extend,
|
||||
genPropsAccessExp,
|
||||
isGloballyAllowed,
|
||||
isString,
|
||||
} from '@vue/shared'
|
||||
import {
|
||||
BindingTypes,
|
||||
NewlineType,
|
||||
|
@ -110,19 +116,26 @@ export function genExpression(
|
|||
|
||||
function genIdentifier(
|
||||
raw: string,
|
||||
{ options, helper, identifiers }: CodegenContext,
|
||||
context: CodegenContext,
|
||||
loc?: SourceLocation,
|
||||
assignment?: string,
|
||||
id?: Identifier,
|
||||
parent?: Node,
|
||||
parentStack?: Node[],
|
||||
): CodeFragment[] {
|
||||
const { options, helper, identifiers } = context
|
||||
const { inline, bindingMetadata } = options
|
||||
let name: string | undefined = raw
|
||||
|
||||
const idMap = identifiers[raw]
|
||||
if (idMap && idMap.length) {
|
||||
return [[idMap[0], NewlineType.None, loc]]
|
||||
const replacement = idMap[0]
|
||||
if (isString(replacement)) {
|
||||
return [[replacement, NewlineType.None, loc]]
|
||||
} else {
|
||||
// replacement is an expression - process it again
|
||||
return genExpression(replacement, context, assignment)
|
||||
}
|
||||
}
|
||||
|
||||
let prefix: string | undefined
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
import { type SimpleExpressionNode, walkIdentifiers } from '@vue/compiler-dom'
|
||||
import {
|
||||
type SimpleExpressionNode,
|
||||
createSimpleExpression,
|
||||
walkIdentifiers,
|
||||
} from '@vue/compiler-dom'
|
||||
import { genBlock } from './block'
|
||||
import { genExpression } from './expression'
|
||||
import type { CodegenContext } from '../generate'
|
||||
import type { ForIRNode } from '../ir'
|
||||
import { type CodeFragment, NEWLINE, genCall, genMulti } from './utils'
|
||||
import type { Identifier } from '@babel/types'
|
||||
import { parseExpression } from '@babel/parser'
|
||||
|
||||
export function genFor(
|
||||
oper: ForIRNode,
|
||||
|
@ -23,10 +28,19 @@ export function genFor(
|
|||
|
||||
const [depth, exitScope] = context.enterScope()
|
||||
const propsName = `_ctx${depth}`
|
||||
const idMap: Record<string, string | null> = {}
|
||||
const idMap: Record<string, string | SimpleExpressionNode | null> = {}
|
||||
|
||||
idToPathMap.forEach((path, id) => {
|
||||
idMap[id] = `${propsName}[0].value${path}`
|
||||
idToPathMap.forEach((pathInfo, id) => {
|
||||
const path = `${propsName}[0].value${pathInfo ? pathInfo.path : ''}`
|
||||
if (pathInfo && pathInfo.dynamic) {
|
||||
const node = (idMap[id] = createSimpleExpression(path))
|
||||
const plugins = context.options.expressionPlugins
|
||||
node.ast = parseExpression(`(${path})`, {
|
||||
plugins: plugins ? [...plugins, 'typescript'] : ['typescript'],
|
||||
})
|
||||
} else {
|
||||
idMap[id] = path
|
||||
}
|
||||
})
|
||||
if (rawKey) idMap[rawKey] = `${propsName}[1].value`
|
||||
if (rawIndex) idMap[rawIndex] = `${propsName}[2].value`
|
||||
|
@ -54,7 +68,7 @@ export function genFor(
|
|||
// construct a id -> accessor path map.
|
||||
// e.g. `{ x: { y: [z] }}` -> `Map{ 'z' => '.x.y[0]' }`
|
||||
function parseValueDestructure() {
|
||||
const map = new Map<string, string>()
|
||||
const map = new Map<string, { path: string; dynamic: boolean } | null>()
|
||||
if (value) {
|
||||
rawValue = value && value.content
|
||||
if (value.ast) {
|
||||
|
@ -63,6 +77,7 @@ export function genFor(
|
|||
(id, _, parentStack, ___, isLocal) => {
|
||||
if (isLocal) {
|
||||
let path = ''
|
||||
let isDynamic = false
|
||||
for (let i = 0; i < parentStack.length; i++) {
|
||||
const parent = parentStack[i]
|
||||
const child = parentStack[i + 1] || id
|
||||
|
@ -71,10 +86,10 @@ export function genFor(
|
|||
parent.value === child
|
||||
) {
|
||||
if (parent.computed && parent.key.type !== 'StringLiteral') {
|
||||
// TODO need to process this
|
||||
isDynamic = true
|
||||
path += `[${value.content.slice(
|
||||
parent.key.start!,
|
||||
parent.key.end!,
|
||||
parent.key.start! - 1,
|
||||
parent.key.end! - 1,
|
||||
)}]`
|
||||
} else if (parent.key.type === 'StringLiteral') {
|
||||
path += `[${JSON.stringify(parent.key.value)}]`
|
||||
|
@ -88,13 +103,13 @@ export function genFor(
|
|||
}
|
||||
// TODO handle rest spread
|
||||
}
|
||||
map.set(id.name, path)
|
||||
map.set(id.name, { path, dynamic: isDynamic })
|
||||
}
|
||||
},
|
||||
true,
|
||||
)
|
||||
} else {
|
||||
map.set(rawValue, '')
|
||||
map.set(rawValue, null)
|
||||
}
|
||||
}
|
||||
return map
|
||||
|
|
Loading…
Reference in New Issue