wip: ignore non-ref const mutation cases in codegen

This commit is contained in:
Evan You 2020-11-18 21:16:09 -05:00
parent 8567feb2aa
commit 64160e89cc
5 changed files with 51 additions and 61 deletions

View File

@ -66,7 +66,10 @@ export interface CodegenResult {
}
export interface CodegenContext
extends Omit<Required<CodegenOptions>, 'bindingMetadata' | 'inline'> {
extends Omit<
Required<CodegenOptions>,
'bindingMetadata' | 'inline' | 'isTS'
> {
source: string
code: string
line: number
@ -214,29 +217,33 @@ export function generate(
genFunctionPreamble(ast, preambleContext)
}
// binding optimizations
const optimizeSources =
options.bindingMetadata && !options.inline
? `, $props, $setup, $data, $options`
: ``
const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache']
if (!__BROWSER__ && options.bindingMetadata && !options.inline) {
// binding optimization args
args.push('$props', '$setup', '$data', '$options')
}
const signature =
!__BROWSER__ && options.isTS
? args.map(arg => `${arg}: any`).join(',')
: args.join(',')
// enter render function
if (!ssr) {
if (isSetupInlined) {
if (genScopeId) {
push(`${PURE_ANNOTATION}_withId(`)
}
push(`(_ctx, _cache${optimizeSources}) => {`)
push(`(${signature}) => {`)
} else {
if (genScopeId) {
push(`const render = ${PURE_ANNOTATION}_withId(`)
}
push(`function render(_ctx, _cache${optimizeSources}) {`)
push(`function render(${signature}) {`)
}
} else {
if (genScopeId) {
push(`const ssrRender = ${PURE_ANNOTATION}_withId(`)
}
push(`function ssrRender(_ctx, _push, _parent, _attrs${optimizeSources}) {`)
push(`function ssrRender(${signature}) {`)
}
indent()

View File

@ -124,6 +124,10 @@ interface SharedTransformCodegenOptions {
* This allows the function to directly access setup() local bindings.
*/
inline?: boolean
/**
* Indicates that transforms and codegen should try to output valid TS code
*/
isTS?: boolean
}
export interface TransformOptions extends SharedTransformCodegenOptions {
@ -195,10 +199,6 @@ export interface TransformOptions extends SharedTransformCodegenOptions {
* needed to render inline CSS variables on component root
*/
ssrCssVars?: string
/**
* Indicates that transforms should try to output valid TS code
*/
isTS?: boolean
onError?: (error: CompilerError) => void
}

View File

@ -118,24 +118,19 @@ export function processExpression(
// setup inline mode
if (type === BindingTypes.SETUP_CONST) {
return raw
} else if (type === BindingTypes.SETUP_REF) {
} else if (
type === BindingTypes.SETUP_REF ||
type === BindingTypes.SETUP_MAYBE_REF
) {
// const binding that may or may not be ref
// if it's not a ref, then assignments don't make sense -
// so we ignore the non-ref assignment case and generate code
// that assumes the value to be a ref for more efficiency
return isAssignmentLVal || isUpdateArg
? `${raw}.value`
: `${context.helperString(UNREF)}(${raw})`
} else if (
type === BindingTypes.SETUP_MAYBE_REF ||
type === BindingTypes.SETUP_LET
) {
} else if (type === BindingTypes.SETUP_LET) {
if (isAssignmentLVal) {
if (type === BindingTypes.SETUP_MAYBE_REF) {
// const binding that may or may not be ref
// if it's not a ref, then the assignment doesn't make sense so
// just no-op it
// x = y ---> !isRef(x) ? null : x.value = y
return `!${context.helperString(
IS_REF
)}(${raw}) ? null : ${raw}.value`
} else {
// let binding.
// this is a bit more tricky as we need to cover the case where
// let is a local non-ref value, and we need to replicate the
@ -149,7 +144,6 @@ export function processExpression(
return `${context.helperString(IS_REF)}(${raw})${
context.isTS ? ` //@ts-ignore\n` : ``
} ? ${raw}.value = ${rExpString} : ${raw}`
}
} else if (isUpdateArg) {
// make id replace parent in the code range so the raw update operator
// is removed
@ -158,21 +152,11 @@ export function processExpression(
const { prefix: isPrefix, operator } = parent as UpdateExpression
const prefix = isPrefix ? operator : ``
const postfix = isPrefix ? `` : operator
if (type === BindingTypes.SETUP_MAYBE_REF) {
// const binding that may or may not be ref
// if it's not a ref, then the assignment doesn't make sense so
// just no-op it
// x++ ---> !isRef(x) ? null : x.value++
return `!${context.helperString(
IS_REF
)}(${raw}) ? null : ${prefix}${raw}.value${postfix}`
} else {
// let binding.
// x++ --> isRef(a) ? a.value++ : a++
return `${context.helperString(IS_REF)}(${raw})${
context.isTS ? ` //@ts-ignore\n` : ``
} ? ${prefix}${raw}.value${postfix} : ${prefix}${raw}${postfix}`
}
} else {
return `${context.helperString(UNREF)}(${raw})`
}

View File

@ -124,7 +124,9 @@ export const transformOn: DirectiveTransform = (
exp = createCompoundExpression([
`${
isInlineStatement
? `$event`
? !__BROWSER__ && context.isTS
? `($event: any)`
: `$event`
: `${
!__BROWSER__ && context.isTS ? `\n//@ts-ignore\n` : ``
}(...args)`

View File

@ -1,5 +1,4 @@
import {
ComponentPublicInstance,
getCurrentInstance,
onMounted,
warn,
@ -14,9 +13,7 @@ import { ShapeFlags } from '@vue/shared'
* Runtime helper for SFC's CSS variable injection feature.
* @private
*/
export function useCssVars(
getter: (ctx: ComponentPublicInstance) => Record<string, string>
) {
export function useCssVars(getter: (ctx: any) => Record<string, string>) {
const instance = getCurrentInstance()
/* istanbul ignore next */
if (!instance) {