block.ts 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import type { BlockIRNode } from '../ir'
  2. import {
  3. type CodeFragment,
  4. INDENT_END,
  5. INDENT_START,
  6. NEWLINE,
  7. buildCodeFragment,
  8. genCall,
  9. } from './utils'
  10. import type { CodegenContext } from '../generate'
  11. import { genEffects, genOperations } from './operation'
  12. import { genChildren } from './template'
  13. import { genMulti } from './utils'
  14. export function genBlock(
  15. oper: BlockIRNode,
  16. context: CodegenContext,
  17. args: CodeFragment[] = [],
  18. root?: boolean,
  19. customReturns?: (returns: CodeFragment[]) => CodeFragment[],
  20. ): CodeFragment[] {
  21. return [
  22. '(',
  23. ...args,
  24. ') => {',
  25. INDENT_START,
  26. ...genBlockContent(oper, context, root, customReturns),
  27. INDENT_END,
  28. NEWLINE,
  29. '}',
  30. ]
  31. }
  32. export function genBlockContent(
  33. block: BlockIRNode,
  34. context: CodegenContext,
  35. root?: boolean,
  36. customReturns?: (returns: CodeFragment[]) => CodeFragment[],
  37. ): CodeFragment[] {
  38. const [frag, push] = buildCodeFragment()
  39. const { dynamic, effect, operation, returns } = block
  40. const resetBlock = context.enterBlock(block)
  41. if (root)
  42. for (const name of context.ir.component) {
  43. push(
  44. NEWLINE,
  45. `const _component_${name} = `,
  46. ...genCall(
  47. context.vaporHelper('resolveComponent'),
  48. JSON.stringify(name),
  49. ),
  50. )
  51. }
  52. for (const child of dynamic.children) {
  53. push(...genChildren(child, context, child.id!))
  54. }
  55. push(...genOperations(operation, context))
  56. push(
  57. ...(context.genEffects.length
  58. ? context.genEffects[context.genEffects.length - 1]
  59. : genEffects)(effect, context),
  60. )
  61. push(NEWLINE, `return `)
  62. const returnsCode: CodeFragment[] =
  63. returns.length > 1
  64. ? genMulti(['[', ']', ', '], ...returns.map(n => `n${n}`))
  65. : [`n${returns[0]}`]
  66. push(...(customReturns ? customReturns(returnsCode) : returnsCode))
  67. resetBlock()
  68. return frag
  69. }