Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(compiler-core): make ast.helpers a Set #6774

Merged
merged 2 commits into from Nov 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
162 changes: 81 additions & 81 deletions packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions packages/compiler-core/__tests__/codegen.spec.ts
Expand Up @@ -41,7 +41,7 @@ function createRoot(options: Partial<RootNode> = {}): RootNode {
return {
type: NodeTypes.ROOT,
children: [],
helpers: [],
helpers: new Set(),
components: [],
directives: [],
imports: [],
Expand All @@ -57,7 +57,7 @@ function createRoot(options: Partial<RootNode> = {}): RootNode {
describe('compiler: codegen', () => {
test('module mode preamble', () => {
const root = createRoot({
helpers: [CREATE_VNODE, RESOLVE_DIRECTIVE]
helpers: new Set([CREATE_VNODE, RESOLVE_DIRECTIVE])
})
const { code } = generate(root, { mode: 'module' })
expect(code).toMatch(
Expand All @@ -68,7 +68,7 @@ describe('compiler: codegen', () => {

test('module mode preamble w/ optimizeImports: true', () => {
const root = createRoot({
helpers: [CREATE_VNODE, RESOLVE_DIRECTIVE]
helpers: new Set([CREATE_VNODE, RESOLVE_DIRECTIVE])
})
const { code } = generate(root, { mode: 'module', optimizeImports: true })
expect(code).toMatch(
Expand All @@ -82,7 +82,7 @@ describe('compiler: codegen', () => {

test('function mode preamble', () => {
const root = createRoot({
helpers: [CREATE_VNODE, RESOLVE_DIRECTIVE]
helpers: new Set([CREATE_VNODE, RESOLVE_DIRECTIVE])
})
const { code } = generate(root, { mode: 'function' })
expect(code).toMatch(`const _Vue = Vue`)
Expand All @@ -94,7 +94,7 @@ describe('compiler: codegen', () => {

test('function mode preamble w/ prefixIdentifiers: true', () => {
const root = createRoot({
helpers: [CREATE_VNODE, RESOLVE_DIRECTIVE]
helpers: new Set([CREATE_VNODE, RESOLVE_DIRECTIVE])
})
const { code } = generate(root, {
mode: 'function',
Expand Down
4 changes: 2 additions & 2 deletions packages/compiler-core/src/ast.ts
Expand Up @@ -100,7 +100,7 @@ export type TemplateChildNode =
export interface RootNode extends Node {
type: NodeTypes.ROOT
children: TemplateChildNode[]
helpers: symbol[]
helpers: Set<symbol>
components: string[]
directives: string[]
hoists: (JSChildNode | null)[]
Expand Down Expand Up @@ -556,7 +556,7 @@ export function createRoot(
return {
type: NodeTypes.ROOT,
children,
helpers: [],
helpers: new Set(),
components: [],
directives: [],
hoists: [],
Expand Down
26 changes: 14 additions & 12 deletions packages/compiler-core/src/codegen.ts
Expand Up @@ -208,7 +208,8 @@ export function generate(
ssr
} = context

const hasHelpers = ast.helpers.length > 0
const helpers = Array.from(ast.helpers)
const hasHelpers = helpers.length > 0
const useWithBlock = !prefixIdentifiers && mode !== 'module'
const genScopeId = !__BROWSER__ && scopeId != null && mode === 'module'
const isSetupInlined = !__BROWSER__ && !!options.inline
Expand Down Expand Up @@ -249,7 +250,7 @@ export function generate(
// function mode const declarations should be inside with block
// also they should be renamed to avoid collision with user properties
if (hasHelpers) {
push(`const { ${ast.helpers.map(aliasHelper).join(', ')} } = _Vue`)
push(`const { ${helpers.map(aliasHelper).join(', ')} } = _Vue`)
push(`\n`)
newline()
}
Expand Down Expand Up @@ -330,11 +331,10 @@ function genFunctionPreamble(ast: RootNode, context: CodegenContext) {
// In prefix mode, we place the const declaration at top so it's done
// only once; But if we not prefixing, we place the declaration inside the
// with block so it doesn't incur the `in` check cost for every helper access.
if (ast.helpers.length > 0) {
const helpers = Array.from(ast.helpers)
if (helpers.length > 0) {
if (!__BROWSER__ && prefixIdentifiers) {
push(
`const { ${ast.helpers.map(aliasHelper).join(', ')} } = ${VueBinding}\n`
)
push(`const { ${helpers.map(aliasHelper).join(', ')} } = ${VueBinding}\n`)
} else {
// "with" mode.
// save Vue in a separate variable to avoid collision
Expand All @@ -350,7 +350,7 @@ function genFunctionPreamble(ast: RootNode, context: CodegenContext) {
CREATE_TEXT,
CREATE_STATIC
]
.filter(helper => ast.helpers.includes(helper))
.filter(helper => helpers.includes(helper))
.map(aliasHelper)
.join(', ')
push(`const { ${staticHelpers} } = _Vue\n`)
Expand Down Expand Up @@ -386,30 +386,32 @@ function genModulePreamble(
} = context

if (genScopeId && ast.hoists.length) {
ast.helpers.push(PUSH_SCOPE_ID, POP_SCOPE_ID)
ast.helpers.add(PUSH_SCOPE_ID)
ast.helpers.add(POP_SCOPE_ID)
}

// generate import statements for helpers
if (ast.helpers.length) {
if (ast.helpers.size) {
const helpers = Array.from(ast.helpers)
if (optimizeImports) {
// when bundled with webpack with code-split, calling an import binding
// as a function leads to it being wrapped with `Object(a.b)` or `(0,a.b)`,
// incurring both payload size increase and potential perf overhead.
// therefore we assign the imports to variables (which is a constant ~50b
// cost per-component instead of scaling with template size)
push(
`import { ${ast.helpers
`import { ${helpers
.map(s => helperNameMap[s])
.join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`
)
push(
`\n// Binding optimization for webpack code-split\nconst ${ast.helpers
`\n// Binding optimization for webpack code-split\nconst ${helpers
.map(s => `_${helperNameMap[s]} = ${helperNameMap[s]}`)
.join(', ')}\n`
)
} else {
push(
`import { ${ast.helpers
`import { ${helpers
.map(s => `${helperNameMap[s]} as _${helperNameMap[s]}`)
.join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`
)
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler-core/src/transform.ts
Expand Up @@ -324,7 +324,7 @@ export function transform(root: RootNode, options: TransformOptions) {
createRootCodegen(root, context)
}
// finalize meta information
root.helpers = [...context.helpers.keys()]
root.helpers = new Set([...context.helpers.keys()])
root.components = [...context.components]
root.directives = [...context.directives]
root.imports = context.imports
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler-sfc/src/compileScript.ts
Expand Up @@ -1554,7 +1554,7 @@ export function compileScript(
// avoid duplicated unref import
// as this may get injected by the render function preamble OR the
// css vars codegen
if (ast && ast.helpers.includes(UNREF)) {
if (ast && ast.helpers.has(UNREF)) {
helperImports.delete('unref')
}
returned = code
Expand Down
4 changes: 2 additions & 2 deletions packages/compiler-ssr/__tests__/ssrInjectCssVars.spec.ts
Expand Up @@ -127,10 +127,10 @@ describe('ssr: inject <style vars>', () => {
}"
`)
expect(result.ast.helpers).toMatchInlineSnapshot(`
Array [
Set {
Symbol(mergeProps),
Symbol(unref),
]
}
`)
})
})
9 changes: 6 additions & 3 deletions packages/compiler-ssr/src/ssrCodegenTransform.ts
Expand Up @@ -49,7 +49,7 @@ export function ssrCodegenTransform(ast: RootNode, options: CompilerOptions) {
createCompoundExpression([`const _cssVars = { style: `, varsExp, `}`])
)
Array.from(cssContext.helpers.keys()).forEach(helper => {
if (!ast.helpers.includes(helper)) ast.helpers.push(helper)
ast.helpers.add(helper)
})
}

Expand All @@ -61,10 +61,13 @@ export function ssrCodegenTransform(ast: RootNode, options: CompilerOptions) {
// Finalize helpers.
// We need to separate helpers imported from 'vue' vs. '@vue/server-renderer'
ast.ssrHelpers = Array.from(
new Set([...ast.helpers.filter(h => h in ssrHelpers), ...context.helpers])
new Set([
...Array.from(ast.helpers).filter(h => h in ssrHelpers),
...context.helpers
])
)

ast.helpers = ast.helpers.filter(h => !(h in ssrHelpers))
ast.helpers = new Set(Array.from(ast.helpers).filter(h => !(h in ssrHelpers)))
}

export type SSRTransformContext = ReturnType<typeof createSSRTransformContext>
Expand Down