File size: 3,993 Bytes
4cadbaf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
"use strict";

exports.__esModule = true;
exports.default = void 0;
var _utils = require("../utils");
function isRemoved(path) {
  if (path.removed) return true;
  if (!path.parentPath) return false;
  if (path.listKey) {
    var _path$parentPath$node;
    if (!((_path$parentPath$node = path.parentPath.node) != null && (_path$parentPath$node = _path$parentPath$node[path.listKey]) != null && _path$parentPath$node.includes(path.node))) return true;
  } else {
    if (path.parentPath.node[path.key] !== path.node) return true;
  }
  return isRemoved(path.parentPath);
}
var _default = callProvider => {
  function property(object, key, placement, path) {
    return callProvider({
      kind: "property",
      object,
      key,
      placement
    }, path);
  }
  function handleReferencedIdentifier(path) {
    const {
      node: {
        name
      },
      scope
    } = path;
    if (scope.getBindingIdentifier(name)) return;
    callProvider({
      kind: "global",
      name
    }, path);
  }
  function analyzeMemberExpression(path) {
    const key = (0, _utils.resolveKey)(path.get("property"), path.node.computed);
    return {
      key,
      handleAsMemberExpression: !!key && key !== "prototype"
    };
  }
  return {
    // Symbol(), new Promise
    ReferencedIdentifier(path) {
      const {
        parentPath
      } = path;
      if (parentPath.isMemberExpression({
        object: path.node
      }) && analyzeMemberExpression(parentPath).handleAsMemberExpression) {
        return;
      }
      handleReferencedIdentifier(path);
    },
    "MemberExpression|OptionalMemberExpression"(path) {
      const {
        key,
        handleAsMemberExpression
      } = analyzeMemberExpression(path);
      if (!handleAsMemberExpression) return;
      const object = path.get("object");
      let objectIsGlobalIdentifier = object.isIdentifier();
      if (objectIsGlobalIdentifier) {
        const binding = object.scope.getBinding(object.node.name);
        if (binding) {
          if (binding.path.isImportNamespaceSpecifier()) return;
          objectIsGlobalIdentifier = false;
        }
      }
      const source = (0, _utils.resolveSource)(object);
      let skipObject = property(source.id, key, source.placement, path);
      skipObject || (skipObject = !objectIsGlobalIdentifier || path.shouldSkip || object.shouldSkip || isRemoved(object));
      if (!skipObject) handleReferencedIdentifier(object);
    },
    ObjectPattern(path) {
      const {
        parentPath,
        parent
      } = path;
      let obj;

      // const { keys, values } = Object
      if (parentPath.isVariableDeclarator()) {
        obj = parentPath.get("init");
        // ({ keys, values } = Object)
      } else if (parentPath.isAssignmentExpression()) {
        obj = parentPath.get("right");
        // !function ({ keys, values }) {...} (Object)
        // resolution does not work after properties transform :-(
      } else if (parentPath.isFunction()) {
        const grand = parentPath.parentPath;
        if (grand.isCallExpression() || grand.isNewExpression()) {
          if (grand.node.callee === parent) {
            obj = grand.get("arguments")[path.key];
          }
        }
      }
      let id = null;
      let placement = null;
      if (obj) ({
        id,
        placement
      } = (0, _utils.resolveSource)(obj));
      for (const prop of path.get("properties")) {
        if (prop.isObjectProperty()) {
          const key = (0, _utils.resolveKey)(prop.get("key"));
          if (key) property(id, key, placement, prop);
        }
      }
    },
    BinaryExpression(path) {
      if (path.node.operator !== "in") return;
      const source = (0, _utils.resolveSource)(path.get("right"));
      const key = (0, _utils.resolveKey)(path.get("left"), true);
      if (!key) return;
      callProvider({
        kind: "in",
        object: source.id,
        key,
        placement: source.placement
      }, path);
    }
  };
};
exports.default = _default;