Skip to content

Commit

Permalink
实现代码生成插值类型
Browse files Browse the repository at this point in the history
  • Loading branch information
jindy committed Jun 23, 2022
1 parent f6caae3 commit 43d2774
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 13 deletions.
1 change: 1 addition & 0 deletions src/compiler-core/src/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export const enum NodeTypes {
SIMPLE_EXPRESSION,
ELEMENT,
TEXT,
ROOT,
}
59 changes: 53 additions & 6 deletions src/compiler-core/src/codegen.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import { helperMapName, TO_DISPLAY_STRING } from "./runtimeHelpers"
import { NodeTypes } from "./ast"

export function generate(ast) {
// let code = ""
// code += "return "
const context = createCodegenContext()
const { push } = context
push("return ")

// const VueBinging = "Vue"
// const aliasHelpers = (s) => `${s}: _${s}`
// push(`const { ${ast.helpers.map(aliasHelpers).join(",")} = ${VueBinging}`)
// push("\n")
// push("return ")
genFunctionPreamble(ast, context)
const functionName = "render"
const args = ["_ctx", "_cache"]
const signature = args.join(",")
Expand All @@ -13,7 +22,7 @@ export function generate(ast) {
// const node = ast.codegenNode
// code += `return '${node.content}'`
// code += `return`
push(`return`)
push(`return `)
genNode(ast.codegenNode, context)
// code += `}`
push(`}`)
Expand All @@ -22,20 +31,58 @@ export function generate(ast) {
}
}

function genFunctionPreamble(ast, context) {
const { push } = context
const VueBinging = "Vue"
const aliasHelpers = (s) => `${helperMapName[s]}: _${helperMapName[s]}`
if (ast.helpers.length > 0) {
push(`const { ${ast.helpers.map(aliasHelpers).join(",")} } = ${VueBinging}`)
}
push("\n")
push("return ")
}

function createCodegenContext(): any {
const context = {
code: "",
push(source) {
context.code += source
},
helper(key) {
return `_${helperMapName[key]}`
},
}
return context
}

function genNode(node, context) {
switch (node.type) {
case NodeTypes.TEXT:
genText(node, context)
break
case NodeTypes.INTERPOLATION:
genInterpolation(node, context)
break
case NodeTypes.SIMPLE_EXPRESSION:
genExpression(node, context)
default:
break
}
}

function genExpression(node, context) {
const { push } = context
// const node = ast.codegenNode
push(` '${node.content}'`)
// code += `return '${node.content}'`
// return code
push(`${node.content}`)
}

function genText(node, context) {
const { push } = context
push(`'${node.content}'`)
}

function genInterpolation(node, context) {
const { push, helper } = context
push(`${helper(TO_DISPLAY_STRING)}(`)
genNode(node.content, context)
push(")")
}
1 change: 1 addition & 0 deletions src/compiler-core/src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ function advanceBy(context, length) {
function createRoot(children) {
return {
children,
type: NodeTypes.ROOT,
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/compiler-core/src/runtimeHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const TO_DISPLAY_STRING = Symbol("toDisplayString")

export const helperMapName = {
[TO_DISPLAY_STRING]: "toDisplayString",
}
29 changes: 23 additions & 6 deletions src/compiler-core/src/transform.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { NodeTypes } from "./ast"
import { TO_DISPLAY_STRING } from "./runtimeHelpers"

export function transform(root, options = {}) {
const context = createTransformContext(root, options)
Expand All @@ -7,6 +8,8 @@ export function transform(root, options = {}) {
// 2.修改 text content

createCodegen(root)

root.helpers = [...context.helpers.keys()]
}

function createCodegen(root) {
Expand All @@ -17,6 +20,10 @@ function createTransformContext(root, options) {
const context = {
root,
nodeTransforms: options.nodeTransforms || [],
helpers: new Map(),
helper(key) {
context.helpers.set(key, 1)
},
}
return context
}
Expand All @@ -33,15 +40,25 @@ function traverseNode(node, context) {
transform(node)
}

traverseChildren(node, context)
switch (node.type) {
case NodeTypes.INTERPOLATION:
context.helper(TO_DISPLAY_STRING)
break
case NodeTypes.ELEMENT:
case NodeTypes.ROOT:
traverseChildren(node, context)
break
default:
break
}
}

function traverseChildren(node, context) {
const children = node.children
if (children) {
for (let index = 0; index < children.length; index++) {
const node = children[index]
traverseNode(node, context)
}
// if (children) {
for (let index = 0; index < children.length; index++) {
const node = children[index]
traverseNode(node, context)
}
// }
}
12 changes: 12 additions & 0 deletions src/compiler-core/src/transform/transformExpression.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { NodeTypes } from "../ast"

export function transformExpression(node) {
if (node.type === NodeTypes.INTERPOLATION) {
node.content = processExpression(node.content) //node.content.content
}
}

function processExpression(node) {
node.content = `_ctx.${node.content}`
return node
}
10 changes: 9 additions & 1 deletion src/compiler-core/tests/__snapshots__/codegen.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`codegen string 1`] = `"return function render(_ctx,_cache){return 'hi'}"`;
exports[`codegen interpolation 1`] = `
"const { toDisplayString: _toDisplayString } = Vue
return function render(_ctx,_cache){return _toDisplayString(_ctx.message)}"
`;

exports[`codegen string 1`] = `
"
return function render(_ctx,_cache){return 'hi'}"
`;
11 changes: 11 additions & 0 deletions src/compiler-core/tests/codegen.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { generate } from "../src/codegen"
import { baseParse } from "../src/parse"
import { transform } from "../src/transform"
import { transformExpression } from "../src/transform/transformExpression"

describe("codegen", () => {
it("string", () => {
Expand All @@ -10,4 +11,14 @@ describe("codegen", () => {
// 快照测试
expect(code).toMatchSnapshot()
})

it("interpolation", () => {
const ast = baseParse("{{message}}")
transform(ast, {
nodeTransforms: [transformExpression],
})
const { code } = generate(ast)
// 快照测试
expect(code).toMatchSnapshot()
})
})

0 comments on commit 43d2774

Please sign in to comment.