• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16var parser = require("@babel/parser")
17var traverse = require("@babel/traverse").default
18var generate = require("@babel/generator").default
19
20function parseExpression(expression, isEventFunc) {
21  const keyWordsReg = new RegExp(`^(NaN\\b|isNaN\\b|isFinite\\b|decodeURI\\b|decodeURIComponent\\b|Math\\b|Date\\b|this\\b|true\\b|false\\b|
22    encodeURI\\b|encodeURIComponent\\b|parseInt\\b|parseFloat\\b|null\\b|undefined\\b|Infinity\\b)`, 'g')
23  const internalKeyWords = new RegExp(`^(var\\b|while\\b|with\\b|yield\\b|enum\\b|await\\b|implements\\b|package\\b|for\\b|function\\b|if\\b|import\\b|
24    protected\\b|static\\b|interface\\b|private\\b|public\\b|break\\b|case\\b|class\\b|catch\\b|const\\b|continue\\b|debugger\\b|
25    default\\b|delete\\b|do\\b|else\\b|export\\b|extends\\b|finally\\b|in\\b|instanceof\\b|let\\b|return\\b|super\\b|switch\\b|throw\\b|try\\b)`, 'g')
26  const reservedKeyWords = new RegExp(`^(var\\b|while\\b|with\\b|yield\\b|enum\\b|await\\b|implements\\b|package\\b|for\\b|function\\b|if\\b|import\\b|
27    protected\\b|static\\b|interface\\b|private\\b|public\\b|break\\b|case\\b|class\\b|catch\\b|const\\b|continue\\b|debugger\\b|
28    default\\b|delete\\b|do\\b|else\\b|export\\b|extends\\b|finally\\b|in\\b|instanceof\\b|let\\b|return\\b|super\\b|switch\\b|throw\\b|try\\b|show\\b|tid\\b)$`, 'g')
29  try {
30    if (reservedKeyWords.test(expression)) {
31      throw Error("A data binding parsing error occurred. Do not use the reserved:" + expression).message
32    }
33    let expAst = isEventFunc ? parser.parse('(' + expression + ')') : parser.parse(expression)
34    traverse(expAst, {
35      enter(path) {
36        if (path.parent && path.node.type === "Identifier") {
37          let flag = false
38          if (['ConditionalExpression', 'BinaryExpression'].includes(path.parent.type) ||
39            path.parent.type === 'CallExpression' && path.parent.callee === path.node) {
40            flag = true
41          }
42          else if (path.parent.type === "ObjectProperty" && !path.parent.computed && path.parent.value === path.node) {
43            flag = true
44          }
45          else {
46            flag = addPrefix(path.node, path.parent)
47          }
48          if (flag && !keyWordsReg.test(path.node.name)) {
49            path.node.name = 'this.' + path.node.name
50          }
51        }
52      }
53    })
54    return generate(expAst, { compact: true }).code.replace(';', '').replace(/\"/g, '\'').replace(/\n/g, '')
55  } catch (e) {
56    if (isEventFunc) {
57      throw internalKeyWords.test(expression) ? Error("An event parsing error occurred. Do not use the reserved:" + expression).message :
58        Error("An event parsing error occurred:" + expression).message
59    } else {
60      throw internalKeyWords.test(expression) ? Error("A data binding parsing error occurred. Do not use the reserved:" + expression).message :
61        Error("A data binding parsing error occurred:" + expression).message
62    }
63  }
64}
65
66function addPrefix(node, parent) {
67  const attrArr1 = ['expression', 'argument', 'arguments', 'expressions', 'elements', 'left', 'right']
68  const attrArr2 = ['object', 'property', 'id', 'key']
69  let keyArr = Object.keys(parent)
70  for (let i = 0; i < attrArr1.length; i++) {
71    if (keyArr.includes(attrArr1[i])) {
72      if (parent[attrArr1[i]] === node || ['expressions', 'elements'].includes(attrArr1[i]) &&
73        parent[attrArr1[i]].includes(node)) {
74        return true
75      }
76      if('arguments' === attrArr1[i] && parent.arguments[0].type === 'Identifier') {
77        return true
78      }
79    }
80  }
81  for (let i = 0; i < attrArr2.length; i++) {
82    if (keyArr.includes(attrArr2[i])) {
83      if (parent.computed && parent[attrArr2[i]] === node) {
84        return true
85      } else {
86        if (parent.type === "Property" && parent.key.range[0] === parent.value.range[0] &&
87          parent.key.range[1] === parent.value.range[1]) {
88          node.name = node.name + ":this." + node.name
89        } else if (parent.object === node) {
90          return true
91        }
92      }
93    }
94  }
95  return false
96}
97
98exports.parseExpression = parseExpression
99