block.ts 1.9 KB

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