From: 三咲智子 Kevin Deng Date: Wed, 31 Jan 2024 10:00:16 +0000 (+0800) Subject: refactor(compiler-vapor): extract imports & unify context name X-Git-Tag: v3.6.0-alpha.1~16^2~617 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=21bec835f0ef2ab38b4ca9429bde29b38f37a098;p=thirdparty%2Fvuejs%2Fcore.git refactor(compiler-vapor): extract imports & unify context name --- diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap index efbe8477bb..31c80866d7 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -44,6 +44,7 @@ export function render(_ctx) { exports[`compiler v-bind > .camel modifier w/ dynamic arg 1`] = ` "import { camelize as _camelize } from 'vue'; +import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor'; export function render(_ctx) { const t0 = _template("
") diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index 52be485aaa..1753f163a6 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -20,6 +20,7 @@ interface CodegenOptions extends BaseCodegenOptions { export type CodeFragment = | typeof NEWLINE + | typeof LF | typeof INDENT_START | typeof INDENT_END | string @@ -131,6 +132,8 @@ export interface VaporCodegenResult extends BaseCodegenResult { } export const NEWLINE = Symbol(__DEV__ ? `newline` : ``) +/** increase offset but don't push actual code */ +export const LF = Symbol(__DEV__ ? `line feed` : ``) export const INDENT_START = Symbol(__DEV__ ? `indent start` : ``) export const INDENT_END = Symbol(__DEV__ ? `indent end` : ``) @@ -139,25 +142,22 @@ export function generate( ir: RootIRNode, options: CodegenOptions = {}, ): VaporCodegenResult { - const ctx = new CodegenContext(ir, options) - const { push, helpers, vaporHelpers } = ctx + const context = new CodegenContext(ir, options) + const { push, helpers, vaporHelpers } = context const functionName = 'render' const isSetupInlined = !!options.inline if (isSetupInlined) { push(`(() => {`) } else { - push( - // placeholder for preamble - NEWLINE, - NEWLINE, - `export function ${functionName}(_ctx) {`, - ) + push(NEWLINE, `export function ${functionName}(_ctx) {`) } push(INDENT_START) - ir.template.forEach((template, i) => push(...genTemplate(template, i, ctx))) - push(...genBlockFunctionContent(ir, ctx)) + ir.template.forEach((template, i) => + push(...genTemplate(template, i, context)), + ) + push(...genBlockFunctionContent(ir, context)) push(INDENT_END, NEWLINE) if (isSetupInlined) { @@ -166,18 +166,9 @@ export function generate( push('}') } - let preamble = '' - if (vaporHelpers.size) - // TODO: extract import codegen - preamble = `import { ${[...vaporHelpers] - .map(h => `${h} as _${h}`) - .join(', ')} } from 'vue/vapor';` - if (helpers.size) - preamble = `import { ${[...helpers] - .map(h => `${h} as _${h}`) - .join(', ')} } from 'vue';` + const preamble = genHelperImports(context) + let codegen = genCodeFragment(context) - let codegen = genCodeFragment(ctx) if (!isSetupInlined) { codegen = preamble + codegen } @@ -186,7 +177,7 @@ export function generate( code: codegen, ast: ir, preamble, - map: ctx.map ? ctx.map.toJSON() : undefined, + map: context.map ? context.map.toJSON() : undefined, helpers, vaporHelpers, } @@ -208,6 +199,11 @@ function genCodeFragment(context: CodegenContext) { } else if (frag === INDENT_END) { indentLevel-- continue + } else if (frag === LF) { + pos.line++ + pos.column = 0 + pos.offset++ + continue } if (isString(frag)) frag = [frag] @@ -282,3 +278,20 @@ export function buildCodeFragment(...frag: CodeFragment[]) { const push = frag.push.bind(frag) return [frag, push] as const } + +function genHelperImports({ helpers, vaporHelpers, code }: CodegenContext) { + let imports = '' + if (helpers.size) { + code.unshift(LF) + imports += `import { ${[...helpers] + .map(h => `${h} as _${h}`) + .join(', ')} } from 'vue';\n` + } + if (vaporHelpers.size) { + code.unshift(LF) + imports += `import { ${[...vaporHelpers] + .map(h => `${h} as _${h}`) + .join(', ')} } from 'vue/vapor';\n` + } + return imports +} diff --git a/packages/compiler-vapor/src/generators/block.ts b/packages/compiler-vapor/src/generators/block.ts index 9c57ca98d9..ddae02f025 100644 --- a/packages/compiler-vapor/src/generators/block.ts +++ b/packages/compiler-vapor/src/generators/block.ts @@ -37,10 +37,10 @@ export function genBlockFunction( export function genBlockFunctionContent( ir: BlockFunctionIRNode | RootIRNode, - ctx: CodegenContext, + context: CodegenContext, returnValue?: () => CodeFragment[], ): CodeFragment[] { - const { vaporHelper } = ctx + const { vaporHelper } = context const [frag, push] = buildCodeFragment( NEWLINE, `const n${ir.dynamic.id} = t${ir.templateIndex}()`, @@ -59,11 +59,11 @@ export function genBlockFunctionContent( oper.type === IRNodeTypes.WITH_DIRECTIVE, ) for (const directives of groupDirective(directiveOps)) { - push(...genWithDirective(directives, ctx)) + push(...genWithDirective(directives, context)) } - push(...genOperations(ir.operation, ctx)) - push(...genEffects(ir.effect, ctx)) + push(...genOperations(ir.operation, context)) + push(...genEffects(ir.effect, context)) push( NEWLINE, diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index 4d66f11ced..d1d5575702 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -17,10 +17,10 @@ import { genSetProp } from './prop' import { genSetRef } from './ref' import { genCreateTextNode, genSetText } from './text' -export function genOperations(opers: OperationNode[], ctx: CodegenContext) { +export function genOperations(opers: OperationNode[], context: CodegenContext) { const [frag, push] = buildCodeFragment() for (const operation of opers) { - push(...genOperation(operation, ctx)) + push(...genOperation(operation, context)) } return frag } diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts index 3bd7ada2be..132dad3278 100644 --- a/packages/compiler-vapor/src/transform.ts +++ b/packages/compiler-vapor/src/transform.ts @@ -117,7 +117,7 @@ function createRootContext( ): TransformContext { let globalId = 0 - const ctx: TransformContext = { + const context: TransformContext = { node, parent: null, index: 0, @@ -210,9 +210,9 @@ function createRootContext( this.block.operation.push(...node) }, } - ctx.root = ctx - ctx.reference() - return ctx + context.root = context + context.reference() + return context } function createContext( @@ -220,7 +220,7 @@ function createContext( parent: TransformContext, index: number, ): TransformContext { - const ctx: TransformContext = extend({}, parent, { + return extend({}, parent, { node, parent, index, @@ -228,8 +228,7 @@ function createContext( template: '', childrenTemplate: [], dynamic: genDefaultDynamic(), - } satisfies Partial>) - return ctx + } satisfies Partial>) satisfies TransformContext } // AST -> IR @@ -250,10 +249,10 @@ export function transform( operation: [], } - const ctx = createRootContext(ir, root, options) + const context = createRootContext(ir, root, options) - transformNode(ctx) - ctx.registerTemplate() + transformNode(context) + context.registerTemplate() return ir } @@ -311,17 +310,17 @@ function transformNode( context.template += context.childrenTemplate.filter(Boolean).join('') } -function transformChildren(ctx: TransformContext) { - const { children } = ctx.node +function transformChildren(context: TransformContext) { + const { children } = context.node for (const [i, child] of children.entries()) { - const childContext = createContext(child, ctx, i) + const childContext = createContext(child, context, i) transformNode(childContext) - ctx.childrenTemplate.push(childContext.template) - ctx.dynamic.children[i] = childContext.dynamic + context.childrenTemplate.push(childContext.template) + context.dynamic.children[i] = childContext.dynamic } - processDynamicChildren(ctx) + processDynamicChildren(context) } function processDynamicChildren( diff --git a/packages/compiler-vapor/src/transforms/transformElement.ts b/packages/compiler-vapor/src/transforms/transformElement.ts index aafda37358..a44626b75b 100644 --- a/packages/compiler-vapor/src/transforms/transformElement.ts +++ b/packages/compiler-vapor/src/transforms/transformElement.ts @@ -8,9 +8,9 @@ import { isBuiltInDirective, isReservedProp, isVoidTag } from '@vue/shared' import type { NodeTransform, TransformContext } from '../transform' import { IRNodeTypes, type VaporDirectiveNode } from '../ir' -export const transformElement: NodeTransform = (node, ctx) => { +export const transformElement: NodeTransform = (node, context) => { return function postTransformElement() { - node = ctx.node + node = context.node if ( !( @@ -25,20 +25,20 @@ export const transformElement: NodeTransform = (node, ctx) => { const { tag, props } = node const isComponent = node.tagType === ElementTypes.COMPONENT - ctx.template += `<${tag}` + context.template += `<${tag}` if (props.length) { buildProps( node, - ctx as TransformContext, + context as TransformContext, undefined, isComponent, ) } - ctx.template += `>` + ctx.childrenTemplate.join('') + context.template += `>` + context.childrenTemplate.join('') // TODO remove unnecessary close tag, e.g. if it's the last element of the template if (!isVoidTag(tag)) { - ctx.template += `` + context.template += `` } } } diff --git a/packages/compiler-vapor/src/transforms/transformInterpolation.ts b/packages/compiler-vapor/src/transforms/transformInterpolation.ts index 255ff6763a..f3d55dab91 100644 --- a/packages/compiler-vapor/src/transforms/transformInterpolation.ts +++ b/packages/compiler-vapor/src/transforms/transformInterpolation.ts @@ -2,19 +2,19 @@ import { NodeTypes, type SimpleExpressionNode } from '@vue/compiler-dom' import type { NodeTransform } from '../transform' import { DynamicFlag, IRNodeTypes } from '../ir' -export const transformInterpolation: NodeTransform = (node, ctx) => { +export const transformInterpolation: NodeTransform = (node, context) => { if (node.type !== NodeTypes.INTERPOLATION) return const expr = node.content as SimpleExpressionNode - const parentChildren = ctx.parent ? ctx.parent.node.children : [] - const isFirst = ctx.index === 0 - const isLast = ctx.index === parentChildren.length - 1 - const isRoot = ctx.parent === ctx.root + const parentChildren = context.parent ? context.parent.node.children : [] + const isFirst = context.index === 0 + const isLast = context.index === parentChildren.length - 1 + const isRoot = context.parent === context.root if (isFirst && isLast && !isRoot) { - const parent = ctx.parent! + const parent = context.parent! const parentId = parent.reference() - ctx.registerEffect( + context.registerEffect( [expr], [ { @@ -25,13 +25,13 @@ export const transformInterpolation: NodeTransform = (node, ctx) => { ], ) } else { - const id = ctx.reference() - ctx.dynamic.flags |= DynamicFlag.INSERT | DynamicFlag.NON_TEMPLATE - ctx.registerOperation({ + const id = context.reference() + context.dynamic.flags |= DynamicFlag.INSERT | DynamicFlag.NON_TEMPLATE + context.registerOperation({ type: IRNodeTypes.CREATE_TEXT_NODE, id, }) - ctx.registerEffect( + context.registerEffect( [expr], [ {