defineOptions.ts 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import type { Node } from '@babel/types'
  2. import { unwrapTSNode } from '@vue/compiler-dom'
  3. import type { ScriptCompileContext } from './context'
  4. import { isCallOf } from './utils'
  5. import { DEFINE_PROPS } from './defineProps'
  6. import { DEFINE_EMITS } from './defineEmits'
  7. import { DEFINE_EXPOSE } from './defineExpose'
  8. import { DEFINE_SLOTS } from './defineSlots'
  9. export const DEFINE_OPTIONS = 'defineOptions'
  10. export function processDefineOptions(
  11. ctx: ScriptCompileContext,
  12. node: Node,
  13. ): boolean {
  14. if (!isCallOf(node, DEFINE_OPTIONS)) {
  15. return false
  16. }
  17. if (ctx.hasDefineOptionsCall) {
  18. ctx.error(`duplicate ${DEFINE_OPTIONS}() call`, node)
  19. }
  20. if (node.typeParameters) {
  21. ctx.error(`${DEFINE_OPTIONS}() cannot accept type arguments`, node)
  22. }
  23. if (!node.arguments[0]) return true
  24. ctx.hasDefineOptionsCall = true
  25. ctx.optionsRuntimeDecl = unwrapTSNode(node.arguments[0])
  26. let propsOption = undefined
  27. let emitsOption = undefined
  28. let exposeOption = undefined
  29. let slotsOption = undefined
  30. if (ctx.optionsRuntimeDecl.type === 'ObjectExpression') {
  31. for (const prop of ctx.optionsRuntimeDecl.properties) {
  32. if (
  33. (prop.type === 'ObjectProperty' || prop.type === 'ObjectMethod') &&
  34. prop.key.type === 'Identifier'
  35. ) {
  36. switch (prop.key.name) {
  37. case 'props':
  38. propsOption = prop
  39. break
  40. case 'emits':
  41. emitsOption = prop
  42. break
  43. case 'expose':
  44. exposeOption = prop
  45. break
  46. case 'slots':
  47. slotsOption = prop
  48. break
  49. }
  50. }
  51. }
  52. }
  53. if (propsOption) {
  54. ctx.error(
  55. `${DEFINE_OPTIONS}() cannot be used to declare props. Use ${DEFINE_PROPS}() instead.`,
  56. propsOption,
  57. )
  58. }
  59. if (emitsOption) {
  60. ctx.error(
  61. `${DEFINE_OPTIONS}() cannot be used to declare emits. Use ${DEFINE_EMITS}() instead.`,
  62. emitsOption,
  63. )
  64. }
  65. if (exposeOption) {
  66. ctx.error(
  67. `${DEFINE_OPTIONS}() cannot be used to declare expose. Use ${DEFINE_EXPOSE}() instead.`,
  68. exposeOption,
  69. )
  70. }
  71. if (slotsOption) {
  72. ctx.error(
  73. `${DEFINE_OPTIONS}() cannot be used to declare slots. Use ${DEFINE_SLOTS}() instead.`,
  74. slotsOption,
  75. )
  76. }
  77. return true
  78. }