Skip to content

Commit

Permalink
Merge branch 'script-setup-2'
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Nov 16, 2020
2 parents 3a6b120 + cea8b25 commit e521de1
Show file tree
Hide file tree
Showing 25 changed files with 2,265 additions and 1,109 deletions.
35 changes: 27 additions & 8 deletions packages/compiler-core/src/codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,13 @@ type CodegenNode = TemplateChildNode | JSChildNode | SSRCodegenNode

export interface CodegenResult {
code: string
preamble: string
ast: RootNode
map?: RawSourceMap
}

export interface CodegenContext
extends Omit<Required<CodegenOptions>, 'bindingMetadata'> {
extends Omit<Required<CodegenOptions>, 'bindingMetadata' | 'inline'> {
source: string
code: string
line: number
Expand Down Expand Up @@ -199,12 +200,18 @@ export function generate(
const hasHelpers = ast.helpers.length > 0
const useWithBlock = !prefixIdentifiers && mode !== 'module'
const genScopeId = !__BROWSER__ && scopeId != null && mode === 'module'
const isSetupInlined = !!options.inline

// preambles
// in setup() inline mode, the preamble is generated in a sub context
// and returned separately.
const preambleContext = isSetupInlined
? createCodegenContext(ast, options)
: context
if (!__BROWSER__ && mode === 'module') {
genModulePreamble(ast, context, genScopeId)
genModulePreamble(ast, preambleContext, genScopeId, isSetupInlined)
} else {
genFunctionPreamble(ast, context)
genFunctionPreamble(ast, preambleContext)
}

// binding optimizations
Expand All @@ -213,10 +220,17 @@ export function generate(
: ``
// enter render function
if (!ssr) {
if (genScopeId) {
push(`const render = ${PURE_ANNOTATION}_withId(`)
if (isSetupInlined) {
if (genScopeId) {
push(`${PURE_ANNOTATION}_withId(`)
}
push(`(_ctx, _cache${optimizeSources}) => {`)
} else {
if (genScopeId) {
push(`const render = ${PURE_ANNOTATION}_withId(`)
}
push(`function render(_ctx, _cache${optimizeSources}) {`)
}
push(`function render(_ctx, _cache${optimizeSources}) {`)
} else {
if (genScopeId) {
push(`const ssrRender = ${PURE_ANNOTATION}_withId(`)
Expand Down Expand Up @@ -290,6 +304,7 @@ export function generate(
return {
ast,
code: context.code,
preamble: isSetupInlined ? preambleContext.code : ``,
// SourceMapGenerator does have toJSON() method but it's not in the types
map: context.map ? (context.map as any).toJSON() : undefined
}
Expand Down Expand Up @@ -356,7 +371,8 @@ function genFunctionPreamble(ast: RootNode, context: CodegenContext) {
function genModulePreamble(
ast: RootNode,
context: CodegenContext,
genScopeId: boolean
genScopeId: boolean,
inline?: boolean
) {
const {
push,
Expand Down Expand Up @@ -423,7 +439,10 @@ function genModulePreamble(

genHoists(ast.hoists, context)
newline()
push(`export `)

if (!inline) {
push(`export `)
}
}

function genAssets(
Expand Down
3 changes: 2 additions & 1 deletion packages/compiler-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ export {
TransformOptions,
CodegenOptions,
HoistTransform,
BindingMetadata
BindingMetadata,
BindingTypes
} from './options'
export { baseParse, TextModes } from './parse'
export {
Expand Down
58 changes: 39 additions & 19 deletions packages/compiler-core/src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,47 @@ export type HoistTransform = (
parent: ParentNode
) => void

export const enum BindingTypes {
DATA = 'data',
PROPS = 'props',
SETUP = 'setup',
CONST = 'const',
OPTIONS = 'options'
}

export interface BindingMetadata {
[key: string]: 'data' | 'props' | 'setup' | 'options'
[key: string]: BindingTypes
}

interface SharedTransformCodegenOptions {
/**
* Transform expressions like {{ foo }} to `_ctx.foo`.
* If this option is false, the generated code will be wrapped in a
* `with (this) { ... }` block.
* - This is force-enabled in module mode, since modules are by default strict
* and cannot use `with`
* @default mode === 'module'
*/
prefixIdentifiers?: boolean
/**
* Generate SSR-optimized render functions instead.
* The resulting function must be attached to the component via the
* `ssrRender` option instead of `render`.
*/
ssr?: boolean
/**
* Optional binding metadata analyzed from script - used to optimize
* binding access when `prefixIdentifiers` is enabled.
*/
bindingMetadata?: BindingMetadata
/**
* Compile the function for inlining inside setup().
* This allows the function to directly access setup() local bindings.
*/
inline?: boolean
}

export interface TransformOptions {
export interface TransformOptions extends SharedTransformCodegenOptions {
/**
* An array of node transforms to be applied to every AST node.
*/
Expand Down Expand Up @@ -128,26 +164,15 @@ export interface TransformOptions {
* SFC scoped styles ID
*/
scopeId?: string | null
/**
* Generate SSR-optimized render functions instead.
* The resulting function must be attached to the component via the
* `ssrRender` option instead of `render`.
*/
ssr?: boolean
/**
* SFC `<style vars>` injection string
* needed to render inline CSS variables on component root
*/
ssrCssVars?: string
/**
* Optional binding metadata analyzed from script - used to optimize
* binding access when `prefixIdentifiers` is enabled.
*/
bindingMetadata?: BindingMetadata
onError?: (error: CompilerError) => void
}

export interface CodegenOptions {
export interface CodegenOptions extends SharedTransformCodegenOptions {
/**
* - `module` mode will generate ES module import statements for helpers
* and export the render function as the default export.
Expand Down Expand Up @@ -189,11 +214,6 @@ export interface CodegenOptions {
* @default 'Vue'
*/
runtimeGlobalName?: string
// we need to know this during codegen to generate proper preambles
prefixIdentifiers?: boolean
bindingMetadata?: BindingMetadata
// generate ssr-specific code?
ssr?: boolean
}

export type CompilerOptions = ParserOptions & TransformOptions & CodegenOptions
4 changes: 3 additions & 1 deletion packages/compiler-core/src/runtimeHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const PUSH_SCOPE_ID = Symbol(__DEV__ ? `pushScopeId` : ``)
export const POP_SCOPE_ID = Symbol(__DEV__ ? `popScopeId` : ``)
export const WITH_SCOPE_ID = Symbol(__DEV__ ? `withScopeId` : ``)
export const WITH_CTX = Symbol(__DEV__ ? `withCtx` : ``)
export const UNREF = Symbol(__DEV__ ? `unref` : ``)

// Name mapping for runtime helpers that need to be imported from 'vue' in
// generated code. Make sure these are correctly exported in the runtime!
Expand Down Expand Up @@ -62,7 +63,8 @@ export const helperNameMap: any = {
[PUSH_SCOPE_ID]: `pushScopeId`,
[POP_SCOPE_ID]: `popScopeId`,
[WITH_SCOPE_ID]: `withScopeId`,
[WITH_CTX]: `withCtx`
[WITH_CTX]: `withCtx`,
[UNREF]: `unref`
}

export function registerRuntimeHelpers(helpers: any) {
Expand Down
7 changes: 5 additions & 2 deletions packages/compiler-core/src/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import {
isArray,
NOOP,
PatchFlags,
PatchFlagNames
PatchFlagNames,
EMPTY_OBJ
} from '@vue/shared'
import { defaultOnError } from './errors'
import {
Expand Down Expand Up @@ -122,7 +123,8 @@ export function createTransformContext(
scopeId = null,
ssr = false,
ssrCssVars = ``,
bindingMetadata = {},
bindingMetadata = EMPTY_OBJ,
inline = false,
onError = defaultOnError
}: TransformOptions
): TransformContext {
Expand All @@ -141,6 +143,7 @@ export function createTransformContext(
ssr,
ssrCssVars,
bindingMetadata,
inline,
onError,

// state
Expand Down
10 changes: 5 additions & 5 deletions packages/compiler-core/src/transforms/hoistStatic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,11 +207,11 @@ export function getStaticType(
case NodeTypes.TEXT_CALL:
return getStaticType(node.content, resultCache)
case NodeTypes.SIMPLE_EXPRESSION:
return node.isConstant
? node.isRuntimeConstant
? StaticType.HAS_RUNTIME_CONSTANT
: StaticType.FULL_STATIC
: StaticType.NOT_STATIC
return node.isRuntimeConstant
? StaticType.HAS_RUNTIME_CONSTANT
: node.isConstant
? StaticType.FULL_STATIC
: StaticType.NOT_STATIC
case NodeTypes.COMPOUND_EXPRESSION:
let returnType = StaticType.FULL_STATIC
for (let i = 0; i < node.children.length; i++) {
Expand Down
37 changes: 33 additions & 4 deletions packages/compiler-core/src/transforms/transformElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ import {
isSymbol,
isOn,
isObject,
isReservedProp
isReservedProp,
capitalize,
camelize,
EMPTY_OBJ
} from '@vue/shared'
import { createCompilerError, ErrorCodes } from '../errors'
import {
Expand All @@ -37,7 +40,8 @@ import {
TO_HANDLERS,
TELEPORT,
KEEP_ALIVE,
SUSPENSE
SUSPENSE,
UNREF
} from '../runtimeHelpers'
import {
getInnerRange,
Expand All @@ -50,6 +54,7 @@ import {
} from '../utils'
import { buildSlots } from './vSlot'
import { getStaticType } from './hoistStatic'
import { BindingTypes } from '../options'

// some directive transforms (e.g. v-model) may return a symbol for runtime
// import, which should be used instead of a resolveDirective call.
Expand Down Expand Up @@ -246,8 +251,32 @@ export function resolveComponentType(
}

// 3. user component (from setup bindings)
if (context.bindingMetadata[tag] === 'setup') {
return `$setup[${JSON.stringify(tag)}]`
const bindings = context.bindingMetadata
if (bindings !== EMPTY_OBJ) {
const checkType = (type: BindingTypes) => {
let resolvedTag = tag
if (
bindings[resolvedTag] === type ||
bindings[(resolvedTag = camelize(tag))] === type ||
bindings[(resolvedTag = capitalize(camelize(tag)))] === type
) {
return resolvedTag
}
}
const tagFromSetup = checkType(BindingTypes.SETUP)
if (tagFromSetup) {
return context.inline
? // setup scope bindings may be refs so they need to be unrefed
`${context.helperString(UNREF)}(${tagFromSetup})`
: `$setup[${JSON.stringify(tagFromSetup)}]`
}
const tagFromConst = checkType(BindingTypes.CONST)
if (tagFromConst) {
return context.inline
? // in inline mode, const setup bindings (e.g. imports) can be used as-is
tagFromConst
: `$setup[${JSON.stringify(tagFromConst)}]`
}
}

// 4. user component (resolve)
Expand Down
Loading

0 comments on commit e521de1

Please sign in to comment.