refactor(compiler-vapor): add placeholder for optional argument
This commit is contained in:
parent
72589be6aa
commit
30f98942db
|
@ -13,8 +13,8 @@ import {
|
||||||
LF,
|
LF,
|
||||||
NEWLINE,
|
NEWLINE,
|
||||||
buildCodeFragment,
|
buildCodeFragment,
|
||||||
|
codeFragmentToString,
|
||||||
genCall,
|
genCall,
|
||||||
genCodeFragment,
|
|
||||||
} from './generators/utils'
|
} from './generators/utils'
|
||||||
|
|
||||||
export type CodegenOptions = Omit<BaseCodegenOptions, 'optimizeImports'>
|
export type CodegenOptions = Omit<BaseCodegenOptions, 'optimizeImports'>
|
||||||
|
@ -132,7 +132,7 @@ export function generate(
|
||||||
frag.unshift(...new Array<CodeFragment>(newlineCount).fill(LF))
|
frag.unshift(...new Array<CodeFragment>(newlineCount).fill(LF))
|
||||||
}
|
}
|
||||||
|
|
||||||
let [code, map] = genCodeFragment(frag, context)
|
let [code, map] = codeFragmentToString(frag, context)
|
||||||
if (!inline) {
|
if (!inline) {
|
||||||
code = preamble + code
|
code = preamble + code
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import type { BlockIRNode } from '../ir'
|
import type { BlockIRNode } from '../ir'
|
||||||
import {
|
import {
|
||||||
type CodeFragment,
|
type CodeFragment,
|
||||||
|
DELIMITERS_ARRAY,
|
||||||
INDENT_END,
|
INDENT_END,
|
||||||
INDENT_START,
|
INDENT_START,
|
||||||
NEWLINE,
|
NEWLINE,
|
||||||
SEGMENTS_ARRAY,
|
|
||||||
buildCodeFragment,
|
buildCodeFragment,
|
||||||
genCall,
|
genCall,
|
||||||
genMulti,
|
genMulti,
|
||||||
|
@ -71,7 +71,7 @@ export function genBlockContent(
|
||||||
const returnNodes = returns.map(n => `n${n}`)
|
const returnNodes = returns.map(n => `n${n}`)
|
||||||
const returnsCode: CodeFragment[] =
|
const returnsCode: CodeFragment[] =
|
||||||
returnNodes.length > 1
|
returnNodes.length > 1
|
||||||
? genMulti(SEGMENTS_ARRAY, ...returnNodes)
|
? genMulti(DELIMITERS_ARRAY, ...returnNodes)
|
||||||
: [returnNodes[0] || 'null']
|
: [returnNodes[0] || 'null']
|
||||||
push(...(customReturns ? customReturns(returnsCode) : returnsCode))
|
push(...(customReturns ? customReturns(returnsCode) : returnsCode))
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,11 @@ import {
|
||||||
} from '../ir'
|
} from '../ir'
|
||||||
import {
|
import {
|
||||||
type CodeFragment,
|
type CodeFragment,
|
||||||
|
DELIMITERS_ARRAY,
|
||||||
|
DELIMITERS_ARRAY_NEWLINE,
|
||||||
|
DELIMITERS_OBJECT,
|
||||||
|
DELIMITERS_OBJECT_NEWLINE,
|
||||||
NEWLINE,
|
NEWLINE,
|
||||||
SEGMENTS_ARRAY,
|
|
||||||
SEGMENTS_ARRAY_NEWLINE,
|
|
||||||
SEGMENTS_OBJECT,
|
|
||||||
SEGMENTS_OBJECT_NEWLINE,
|
|
||||||
genCall,
|
genCall,
|
||||||
genMulti,
|
genMulti,
|
||||||
} from './utils'
|
} from './utils'
|
||||||
|
@ -43,13 +43,9 @@ export function genCreateComponent(
|
||||||
...genCall(
|
...genCall(
|
||||||
vaporHelper('createComponent'),
|
vaporHelper('createComponent'),
|
||||||
tag,
|
tag,
|
||||||
rawProps || (slots || dynamicSlots || root ? 'null' : false),
|
rawProps,
|
||||||
slots ? genSlots(slots, context) : dynamicSlots || root ? 'null' : false,
|
slots && genSlots(slots, context),
|
||||||
dynamicSlots
|
dynamicSlots && genDynamicSlots(dynamicSlots, context),
|
||||||
? genDynamicSlots(dynamicSlots, context)
|
|
||||||
: root
|
|
||||||
? 'null'
|
|
||||||
: false,
|
|
||||||
root && 'true',
|
root && 'true',
|
||||||
),
|
),
|
||||||
...genDirectivesForElement(oper.id, context),
|
...genDirectivesForElement(oper.id, context),
|
||||||
|
@ -77,7 +73,7 @@ export function genRawProps(props: IRProps[], context: CodegenContext) {
|
||||||
} else {
|
} else {
|
||||||
let expr: CodeFragment[]
|
let expr: CodeFragment[]
|
||||||
if (props.kind === IRDynamicPropsKind.ATTRIBUTE)
|
if (props.kind === IRDynamicPropsKind.ATTRIBUTE)
|
||||||
expr = genMulti(SEGMENTS_OBJECT, genProp(props, context))
|
expr = genMulti(DELIMITERS_OBJECT, genProp(props, context))
|
||||||
else {
|
else {
|
||||||
expr = genExpression(props.value, context)
|
expr = genExpression(props.value, context)
|
||||||
if (props.handler) expr = genCall(vaporHelper('toHandlers'), expr)
|
if (props.handler) expr = genCall(vaporHelper('toHandlers'), expr)
|
||||||
|
@ -89,7 +85,7 @@ export function genRawProps(props: IRProps[], context: CodegenContext) {
|
||||||
Boolean as any as (v: CodeFragment[] | undefined) => v is CodeFragment[],
|
Boolean as any as (v: CodeFragment[] | undefined) => v is CodeFragment[],
|
||||||
)
|
)
|
||||||
if (frag.length) {
|
if (frag.length) {
|
||||||
return genMulti(SEGMENTS_ARRAY_NEWLINE, ...frag)
|
return genMulti(DELIMITERS_ARRAY_NEWLINE, ...frag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +94,7 @@ function genStaticProps(
|
||||||
context: CodegenContext,
|
context: CodegenContext,
|
||||||
): CodeFragment[] {
|
): CodeFragment[] {
|
||||||
return genMulti(
|
return genMulti(
|
||||||
props.length > 1 ? SEGMENTS_OBJECT_NEWLINE : SEGMENTS_OBJECT,
|
props.length > 1 ? DELIMITERS_OBJECT_NEWLINE : DELIMITERS_OBJECT,
|
||||||
...props.map(prop => genProp(prop, context, true)),
|
...props.map(prop => genProp(prop, context, true)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -147,7 +143,7 @@ function genModelModifiers(
|
||||||
function genSlots(slots: ComponentSlots, context: CodegenContext) {
|
function genSlots(slots: ComponentSlots, context: CodegenContext) {
|
||||||
const slotList = Object.entries(slots)
|
const slotList = Object.entries(slots)
|
||||||
return genMulti(
|
return genMulti(
|
||||||
slotList.length > 1 ? SEGMENTS_OBJECT_NEWLINE : SEGMENTS_OBJECT,
|
slotList.length > 1 ? DELIMITERS_OBJECT_NEWLINE : DELIMITERS_OBJECT,
|
||||||
...slotList.map(([name, slot]) => [name, ': ', ...genBlock(slot, context)]),
|
...slotList.map(([name, slot]) => [name, ': ', ...genBlock(slot, context)]),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -157,10 +153,10 @@ function genDynamicSlots(
|
||||||
context: CodegenContext,
|
context: CodegenContext,
|
||||||
) {
|
) {
|
||||||
const slotsExpr = genMulti(
|
const slotsExpr = genMulti(
|
||||||
dynamicSlots.length > 1 ? SEGMENTS_ARRAY_NEWLINE : SEGMENTS_ARRAY,
|
dynamicSlots.length > 1 ? DELIMITERS_ARRAY_NEWLINE : DELIMITERS_ARRAY,
|
||||||
...dynamicSlots.map(({ name, fn }) =>
|
...dynamicSlots.map(({ name, fn }) =>
|
||||||
genMulti(
|
genMulti(
|
||||||
SEGMENTS_OBJECT_NEWLINE,
|
DELIMITERS_OBJECT_NEWLINE,
|
||||||
['name: ', ...genExpression(name, context)],
|
['name: ', ...genExpression(name, context)],
|
||||||
['fn: ', ...genBlock(fn, context)],
|
['fn: ', ...genBlock(fn, context)],
|
||||||
),
|
),
|
||||||
|
|
|
@ -4,8 +4,9 @@ import { genExpression } from './expression'
|
||||||
import type { CodegenContext } from '../generate'
|
import type { CodegenContext } from '../generate'
|
||||||
import {
|
import {
|
||||||
type CodeFragment,
|
type CodeFragment,
|
||||||
|
type CodeFragmentDelimiters,
|
||||||
|
DELIMITERS_ARRAY,
|
||||||
NEWLINE,
|
NEWLINE,
|
||||||
SEGMENTS_ARRAY,
|
|
||||||
genCall,
|
genCall,
|
||||||
genMulti,
|
genMulti,
|
||||||
} from './utils'
|
} from './utils'
|
||||||
|
@ -28,7 +29,7 @@ export function genWithDirective(
|
||||||
|
|
||||||
const element = `n${opers[0].element}`
|
const element = `n${opers[0].element}`
|
||||||
const directiveItems = opers.map(genDirective)
|
const directiveItems = opers.map(genDirective)
|
||||||
const directives = genMulti(SEGMENTS_ARRAY, ...directiveItems)
|
const directives = genMulti(DELIMITERS_ARRAY, ...directiveItems)
|
||||||
|
|
||||||
return [
|
return [
|
||||||
NEWLINE,
|
NEWLINE,
|
||||||
|
@ -36,24 +37,22 @@ export function genWithDirective(
|
||||||
]
|
]
|
||||||
|
|
||||||
function genDirective({ dir, builtin }: WithDirectiveIRNode): CodeFragment[] {
|
function genDirective({ dir, builtin }: WithDirectiveIRNode): CodeFragment[] {
|
||||||
const NULL = 'void 0'
|
|
||||||
|
|
||||||
const directive = genDirective()
|
const directive = genDirective()
|
||||||
const value = dir.exp
|
const value = dir.exp && ['() => ', ...genExpression(dir.exp, context)]
|
||||||
? ['() => ', ...genExpression(dir.exp, context)]
|
const argument = dir.arg && genExpression(dir.arg, context)
|
||||||
: dir.arg || dir.modifiers.length
|
const modifiers = !!dir.modifiers.length && [
|
||||||
? NULL
|
'{ ',
|
||||||
: false
|
genDirectiveModifiers(dir.modifiers),
|
||||||
const argument = dir.arg
|
' }',
|
||||||
? genExpression(dir.arg, context)
|
]
|
||||||
: dir.modifiers.length
|
|
||||||
? NULL
|
|
||||||
: false
|
|
||||||
const modifiers = dir.modifiers.length
|
|
||||||
? ['{ ', genDirectiveModifiers(dir.modifiers), ' }']
|
|
||||||
: false
|
|
||||||
|
|
||||||
return genMulti(SEGMENTS_ARRAY, directive, value, argument, modifiers)
|
return genMulti(
|
||||||
|
DELIMITERS_ARRAY.concat('void 0') as CodeFragmentDelimiters,
|
||||||
|
directive,
|
||||||
|
value,
|
||||||
|
argument,
|
||||||
|
modifiers,
|
||||||
|
)
|
||||||
|
|
||||||
function genDirective() {
|
function genDirective() {
|
||||||
const {
|
const {
|
||||||
|
|
|
@ -8,8 +8,8 @@ import type { SetDynamicEventsIRNode, SetEventIRNode } from '../ir'
|
||||||
import { genExpression } from './expression'
|
import { genExpression } from './expression'
|
||||||
import {
|
import {
|
||||||
type CodeFragment,
|
type CodeFragment,
|
||||||
|
DELIMITERS_OBJECT_NEWLINE,
|
||||||
NEWLINE,
|
NEWLINE,
|
||||||
SEGMENTS_OBJECT_NEWLINE,
|
|
||||||
genCall,
|
genCall,
|
||||||
genMulti,
|
genMulti,
|
||||||
} from './utils'
|
} from './utils'
|
||||||
|
@ -59,7 +59,7 @@ export function genSetEvent(
|
||||||
if (!options.length && !nonKeys.length && !keys.length && !effect) return
|
if (!options.length && !nonKeys.length && !keys.length && !effect) return
|
||||||
|
|
||||||
return genMulti(
|
return genMulti(
|
||||||
SEGMENTS_OBJECT_NEWLINE,
|
DELIMITERS_OBJECT_NEWLINE,
|
||||||
!!nonKeys.length && ['modifiers: ', genArrayExpression(nonKeys)],
|
!!nonKeys.length && ['modifiers: ', genArrayExpression(nonKeys)],
|
||||||
!!keys.length && ['keys: ', genArrayExpression(keys)],
|
!!keys.length && ['keys: ', genArrayExpression(keys)],
|
||||||
effect && ['effect: true'],
|
effect && ['effect: true'],
|
||||||
|
|
|
@ -36,7 +36,7 @@ export function genIf(
|
||||||
vaporHelper('createIf'),
|
vaporHelper('createIf'),
|
||||||
conditionExpr,
|
conditionExpr,
|
||||||
positiveArg,
|
positiveArg,
|
||||||
negativeArg || (once ? 'null' : false),
|
negativeArg,
|
||||||
once && 'true',
|
once && 'true',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
@ -14,9 +14,9 @@ import {
|
||||||
import { genExpression } from './expression'
|
import { genExpression } from './expression'
|
||||||
import {
|
import {
|
||||||
type CodeFragment,
|
type CodeFragment,
|
||||||
|
DELIMITERS_ARRAY,
|
||||||
|
DELIMITERS_OBJECT,
|
||||||
NEWLINE,
|
NEWLINE,
|
||||||
SEGMENTS_ARRAY,
|
|
||||||
SEGMENTS_OBJECT,
|
|
||||||
genCall,
|
genCall,
|
||||||
genMulti,
|
genMulti,
|
||||||
} from './utils'
|
} from './utils'
|
||||||
|
@ -51,7 +51,7 @@ export function genSetProp(
|
||||||
return [
|
return [
|
||||||
NEWLINE,
|
NEWLINE,
|
||||||
...genCall(
|
...genCall(
|
||||||
vaporHelper(helperName),
|
[vaporHelper(helperName), null],
|
||||||
`n${oper.element}`,
|
`n${oper.element}`,
|
||||||
omitKey ? false : genExpression(key, context),
|
omitKey ? false : genExpression(key, context),
|
||||||
genPropValue(values, context),
|
genPropValue(values, context),
|
||||||
|
@ -87,7 +87,7 @@ function genLiteralObjectProps(
|
||||||
context: CodegenContext,
|
context: CodegenContext,
|
||||||
): CodeFragment[] {
|
): CodeFragment[] {
|
||||||
return genMulti(
|
return genMulti(
|
||||||
SEGMENTS_OBJECT,
|
DELIMITERS_OBJECT,
|
||||||
...props.map(prop => [
|
...props.map(prop => [
|
||||||
...genPropKey(prop, context),
|
...genPropKey(prop, context),
|
||||||
`: `,
|
`: `,
|
||||||
|
@ -130,7 +130,7 @@ function genPropValue(values: SimpleExpressionNode[], context: CodegenContext) {
|
||||||
return genExpression(values[0], context)
|
return genExpression(values[0], context)
|
||||||
}
|
}
|
||||||
return genMulti(
|
return genMulti(
|
||||||
SEGMENTS_ARRAY,
|
DELIMITERS_ARRAY,
|
||||||
...values.map(expr => genExpression(expr, context)),
|
...values.map(expr => genExpression(expr, context)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@ import type { CreateTextNodeIRNode, SetTextIRNode } from '../ir'
|
||||||
import { genExpression } from './expression'
|
import { genExpression } from './expression'
|
||||||
import {
|
import {
|
||||||
type CodeFragment,
|
type CodeFragment,
|
||||||
|
DELIMITERS_ARRAY,
|
||||||
NEWLINE,
|
NEWLINE,
|
||||||
SEGMENTS_ARRAY,
|
|
||||||
genCall,
|
genCall,
|
||||||
genMulti,
|
genMulti,
|
||||||
} from './utils'
|
} from './utils'
|
||||||
|
@ -37,7 +37,7 @@ export function genCreateTextNode(
|
||||||
...genCall(vaporHelper('createTextNode'), [
|
...genCall(vaporHelper('createTextNode'), [
|
||||||
effect && '() => ',
|
effect && '() => ',
|
||||||
...genMulti(
|
...genMulti(
|
||||||
SEGMENTS_ARRAY,
|
DELIMITERS_ARRAY,
|
||||||
...values.map(value => genExpression(value, context)),
|
...values.map(value => genExpression(value, context)),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
|
|
|
@ -27,22 +27,34 @@ export type CodeFragment =
|
||||||
| FalsyValue
|
| FalsyValue
|
||||||
export type CodeFragments = Exclude<CodeFragment, any[]> | CodeFragment[]
|
export type CodeFragments = Exclude<CodeFragment, any[]> | CodeFragment[]
|
||||||
|
|
||||||
export function buildCodeFragment(...frag: CodeFragment[]) {
|
export function buildCodeFragment(
|
||||||
|
...frag: CodeFragment[]
|
||||||
|
): [CodeFragment[], (...items: CodeFragment[]) => number] {
|
||||||
const push = frag.push.bind(frag)
|
const push = frag.push.bind(frag)
|
||||||
return [frag, push] as const
|
return [frag, push]
|
||||||
}
|
}
|
||||||
|
|
||||||
type Segments = [
|
export type CodeFragmentDelimiters = [
|
||||||
left: CodeFragments,
|
left: CodeFragments,
|
||||||
right: CodeFragments,
|
right: CodeFragments,
|
||||||
segment: CodeFragments,
|
delimiter: CodeFragments,
|
||||||
|
placeholder?: CodeFragments,
|
||||||
]
|
]
|
||||||
|
|
||||||
export function genMulti(
|
export function genMulti(
|
||||||
[left, right, seg]: Segments,
|
[left, right, seg, placeholder]: CodeFragmentDelimiters,
|
||||||
...frags: CodeFragments[]
|
...frags: CodeFragments[]
|
||||||
): CodeFragment[] {
|
): CodeFragment[] {
|
||||||
|
if (placeholder) {
|
||||||
|
while (!frags[frags.length - 1]) {
|
||||||
|
frags.pop()
|
||||||
|
}
|
||||||
|
frags = frags.map(frag => frag || placeholder)
|
||||||
|
} else {
|
||||||
|
frags = frags.filter(Boolean)
|
||||||
|
}
|
||||||
|
|
||||||
const frag: CodeFragment[] = []
|
const frag: CodeFragment[] = []
|
||||||
frags = frags.filter(Boolean)
|
|
||||||
push(left)
|
push(left)
|
||||||
for (let [i, fn] of (
|
for (let [i, fn] of (
|
||||||
frags as Array<Exclude<CodeFragments, FalsyValue>>
|
frags as Array<Exclude<CodeFragments, FalsyValue>>
|
||||||
|
@ -58,27 +70,30 @@ export function genMulti(
|
||||||
frag.push(...fn)
|
frag.push(...fn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const SEGMENTS_ARRAY: Segments = ['[', ']', ', ']
|
export const DELIMITERS_ARRAY: CodeFragmentDelimiters = ['[', ']', ', ']
|
||||||
export const SEGMENTS_ARRAY_NEWLINE: Segments = [
|
export const DELIMITERS_ARRAY_NEWLINE: CodeFragmentDelimiters = [
|
||||||
['[', INDENT_START, NEWLINE],
|
['[', INDENT_START, NEWLINE],
|
||||||
[INDENT_END, NEWLINE, ']'],
|
[INDENT_END, NEWLINE, ']'],
|
||||||
[', ', NEWLINE],
|
[', ', NEWLINE],
|
||||||
]
|
]
|
||||||
export const SEGMENTS_OBJECT: Segments = ['{ ', ' }', ', ']
|
export const DELIMITERS_OBJECT: CodeFragmentDelimiters = ['{ ', ' }', ', ']
|
||||||
export const SEGMENTS_OBJECT_NEWLINE: Segments = [
|
export const DELIMITERS_OBJECT_NEWLINE: CodeFragmentDelimiters = [
|
||||||
['{', INDENT_START, NEWLINE],
|
['{', INDENT_START, NEWLINE],
|
||||||
[INDENT_END, NEWLINE, '}'],
|
[INDENT_END, NEWLINE, '}'],
|
||||||
[', ', NEWLINE],
|
[', ', NEWLINE],
|
||||||
]
|
]
|
||||||
|
|
||||||
export function genCall(
|
export function genCall(
|
||||||
name: string,
|
name: string | [name: string, placeholder?: CodeFragments],
|
||||||
...frags: CodeFragments[]
|
...frags: CodeFragments[]
|
||||||
): CodeFragment[] {
|
): CodeFragment[] {
|
||||||
return [name, ...genMulti(['(', ')', ', '], ...frags)]
|
const hasPlaceholder = isArray(name)
|
||||||
|
const fnName = hasPlaceholder ? name[0] : name
|
||||||
|
const placeholder = hasPlaceholder ? name[1] : 'null'
|
||||||
|
return [fnName, ...genMulti(['(', ')', ', ', placeholder], ...frags)]
|
||||||
}
|
}
|
||||||
|
|
||||||
export function genCodeFragment(
|
export function codeFragmentToString(
|
||||||
code: CodeFragment[],
|
code: CodeFragment[],
|
||||||
context: CodegenContext,
|
context: CodegenContext,
|
||||||
): [code: string, map: CodegenSourceMapGenerator | undefined] {
|
): [code: string, map: CodegenSourceMapGenerator | undefined] {
|
||||||
|
|
|
@ -17,7 +17,7 @@ export {
|
||||||
genCall,
|
genCall,
|
||||||
genMulti,
|
genMulti,
|
||||||
buildCodeFragment,
|
buildCodeFragment,
|
||||||
genCodeFragment,
|
codeFragmentToString,
|
||||||
type CodeFragment,
|
type CodeFragment,
|
||||||
} from './generators/utils'
|
} from './generators/utils'
|
||||||
export {
|
export {
|
||||||
|
|
Loading…
Reference in New Issue