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

View File

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

View File

@ -118,24 +118,19 @@ export function processExpression(
// setup inline mode // setup inline mode
if (type === BindingTypes.SETUP_CONST) { if (type === BindingTypes.SETUP_CONST) {
return raw 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 return isAssignmentLVal || isUpdateArg
? `${raw}.value` ? `${raw}.value`
: `${context.helperString(UNREF)}(${raw})` : `${context.helperString(UNREF)}(${raw})`
} else if ( } else if (type === BindingTypes.SETUP_LET) {
type === BindingTypes.SETUP_MAYBE_REF ||
type === BindingTypes.SETUP_LET
) {
if (isAssignmentLVal) { 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. // let binding.
// this is a bit more tricky as we need to cover the case where // 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 // 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})${ return `${context.helperString(IS_REF)}(${raw})${
context.isTS ? ` //@ts-ignore\n` : `` context.isTS ? ` //@ts-ignore\n` : ``
} ? ${raw}.value = ${rExpString} : ${raw}` } ? ${raw}.value = ${rExpString} : ${raw}`
}
} else if (isUpdateArg) { } else if (isUpdateArg) {
// make id replace parent in the code range so the raw update operator // make id replace parent in the code range so the raw update operator
// is removed // is removed
@ -158,21 +152,11 @@ export function processExpression(
const { prefix: isPrefix, operator } = parent as UpdateExpression const { prefix: isPrefix, operator } = parent as UpdateExpression
const prefix = isPrefix ? operator : `` const prefix = isPrefix ? operator : ``
const postfix = 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. // let binding.
// x++ --> isRef(a) ? a.value++ : a++ // x++ --> isRef(a) ? a.value++ : a++
return `${context.helperString(IS_REF)}(${raw})${ return `${context.helperString(IS_REF)}(${raw})${
context.isTS ? ` //@ts-ignore\n` : `` context.isTS ? ` //@ts-ignore\n` : ``
} ? ${prefix}${raw}.value${postfix} : ${prefix}${raw}${postfix}` } ? ${prefix}${raw}.value${postfix} : ${prefix}${raw}${postfix}`
}
} else { } else {
return `${context.helperString(UNREF)}(${raw})` return `${context.helperString(UNREF)}(${raw})`
} }

View File

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

View File

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