quasar

Форк
0
/
ast.js 
86 строк · 3.2 Кб
1
const
2
  recast = require('recast'),
3
  parser = require('recast/parsers/babel')
4

5
// Analyze component JS file
6
module.exports.evaluate = (source, lookup, callback) => {
7
  const ast = recast.parse(source, { parser })
8
  for (const node of ast.program.body) {
9
    if (node.type === 'ExportDefaultDeclaration') {
10
      const properties
11
        = node.declaration.properties // When exporting a plain object (`export default { ... }`)
12
        || node.declaration.arguments[ 0 ].properties // When exporting a wrapped object (`export default defineComponent({ ... })`)
13
      for (const property of properties) {
14
        const propName = property.key.name
15
        if (lookup.includes(propName)) {
16
          const innerProps = property.value.properties
17
          if (innerProps !== void 0) { // TODO vue3 - fix AST
18
            for (const innerProp of innerProps) {
19
              let definition = null
20
              if (propName === 'props' && innerProp.value) {
21
                definition = getPropDefinition(innerProp)
22
              }
23
              innerProp.key !== void 0 && callback(propName, innerProp.key.name, definition)
24
            }
25
          }
26
        }
27
      }
28
    }
29
  }
30
}
31

32
function getPropDefinition (innerProp) {
33
  let definition = {}
34
  if (innerProp.value.type === 'Identifier') {
35
    definition.type = innerProp.value.name
36
  }
37
  else if (innerProp.value.type === 'ArrayExpression') {
38
    definition.type = innerProp.value.elements.map(e => e.name)
39
  }
40
  else if (innerProp.value.type !== 'ConditionalExpression') {
41
    const jsonContent = innerProp.value.properties.map(p => {
42
      let value
43
      if (p.value) {
44
        if (p.value.name || p.value.value) {
45
          value = `"${ p.value.name || p.value.value }"`
46
        }
47
        else if (p.value.type === 'ArrowFunctionExpression') {
48
          if (p.value.body.type === 'ArrayExpression') {
49
            value = `[${ p.value.body.elements.map(e => e.extra.raw || e.value).join(', ') }]`
50
          }
51
          else if (!p.value.body.callee || !p.value.body.callee.object || !p.value.body.callee.object.elements) {
52
            return ''
53
          }
54
          else {
55
            value = `[${ p.value.body.callee.object.elements.map(e => e.extra.raw || e.value).join(', ') }]`
56
          }
57
        }
58
        else if (p.value.type === 'FunctionExpression') {
59
          value = `[${ p.value.body.body.argument.callee.object.elements.map(e => e.extra.raw || e.value).join(', ') }]`
60
        }
61
      }
62
      else {
63
        return ''
64
      }
65
      if (value === void 0) {
66
        return ''
67
      }
68
      return `"${ p.key.name }": ${ value }`
69
    }).filter(c => !!c).map(c => c.replace(/'/g, '"')).join(', ')
70
    definition = JSON.parse(`{${ jsonContent }}`)
71
  }
72

73
  if (Array.isArray(innerProp.value.properties) === true) {
74
    const defaultVal = innerProp.value.properties.find(p => p.key.name === 'default')
75
    if (defaultVal !== void 0 && defaultVal.value !== void 0 && defaultVal.value.type === 'NullLiteral') {
76
      if (Array.isArray(definition.type) === true && definition.type.indexOf('null') === -1) {
77
        definition.type.push('null')
78
      }
79
      else if (typeof definition.type === 'string') {
80
        definition.type = [ definition.type, 'null' ]
81
      }
82
    }
83
  }
84

85
  return definition
86
}
87

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.