Exemple #1
0
    def enter_ClassDef(self, node):
        class_name = node_utils.get_name(node, self._ast)
        last_line = max(node.lineno, node.body[0].lineno - 1)

        # Python2
        ops = match_opcodes_multiline(self.traces, node.lineno, last_line,
                                      [("BUILD_CLASS", class_name)])
        d = None
        if ops:
            _, _, data = ops[0]
            d = _unwrap(data)
        else:
            # Python3
            ops = match_opcodes_multiline(self.traces, node.lineno, last_line,
                                          [("LOAD_BUILD_CLASS", None),
                                           ("STORE_NAME", class_name)])
            if len(ops) == 2:
                _, _, data = ops[1]
                d = _unwrap(data)
        assert d, "Did not get pytype data for class %s" % class_name
        defn = self.add_local_def(node,
                                  data=data,
                                  doc=DocString.from_node(self._ast, node))
        self.classmap[d[0]] = defn
        super(IndexVisitor, self).enter_ClassDef(node)
Exemple #2
0
    def enter_ClassDef(self, node):
        class_name = node_utils.get_name(node, self._ast)
        last_line = max(node.lineno, node.body[0].lineno - 1)

        # Python2
        ops = match_opcodes_multiline(self.traces, node.lineno, last_line,
                                      [("BUILD_CLASS", class_name)])
        d = None
        if ops:
            _, _, data = ops[0]
            d = _unwrap(data)
        else:
            # Python3
            ops = match_opcodes_multiline(
                self.traces,
                node.lineno,
                last_line,
                [
                    ("LOAD_BUILD_CLASS", None),
                    ("STORE_NAME", class_name),
                    # Classes defined within a function generate a STORE_FAST op.
                    ("STORE_FAST", class_name),
                ])
            # pytype sometimes analyses this twice, leading to duplicate opcode
            # traces. We only want the first two in the list.
            if (len(ops) >= 2 and ops[0][0] == "LOAD_BUILD_CLASS"
                    and ops[1][0] in ("STORE_NAME", "STORE_FAST")):
                _, _, data = ops[1]
                d = _unwrap(data)
        assert d, "Did not get pytype data for class %s" % class_name
        defn = self.add_local_def(node,
                                  data=data,
                                  doc=DocString.from_node(self._ast, node))
        self.classmap[d[0]] = defn
        super(IndexVisitor, self).enter_ClassDef(node)
Exemple #3
0
    def enter_ClassDef(self, node):
        class_name = node_utils.get_name(node, self._ast)
        last_line = max(node.lineno, node.body[0].lineno - 1)

        ops = match_opcodes_multiline(
            self.traces,
            node.lineno,
            last_line,
            [
                ("LOAD_BUILD_CLASS", None),
                ("STORE_NAME", class_name),
                # Classes defined within a function generate a STORE_FAST or
                # STORE_DEREF op.
                ("STORE_FAST", class_name),
                ("STORE_DEREF", class_name),
                # A class being declared global anywhere generates a STORE_GLOBAL op.
                ("STORE_GLOBAL", class_name),
            ])
        # pytype sometimes analyses this twice, leading to duplicate opcode
        # traces. We only want the first two in the list.
        if (len(ops) >= 2 and ops[0][0] == "LOAD_BUILD_CLASS"
                and ops[1][0] in ("STORE_NAME", "STORE_FAST", "STORE_DEREF",
                                  "STORE_GLOBAL")):
            _, _, data = ops[1]
            d = _unwrap(data)

        assert d, "Did not get pytype data for class %s at line %d" % (
            class_name, node.lineno)
        defn = self.add_local_def(node,
                                  data=data,
                                  doc=DocString.from_node(self._ast, node))
        self.classmap[d[0]] = defn
        super().enter_ClassDef(node)
Exemple #4
0
    def make_ref(self, node, **kwargs):
        """Make a reference from a node."""

        assert "data" in kwargs  # required kwarg
        args = {
            "name": node_utils.get_name(node, self._ast),
            "scope": self.scope_id(),
            "ref_scope": None,
            "typ": node_utils.typename(node),
            "location": get_location(node),
            "target": None,
        }
        args.update(kwargs)
        return Reference(**args)
Exemple #5
0
 def add_closure_ref(self, node, **kwargs):
     """Look for node.name up the chain of scopes."""
     name = node_utils.get_name(node, self._ast)
     env, _ = self.current_env.lookup(name)
     if env:
         kwargs.update({"ref_scope": env.scope})
     else:
         # This should never happen! If python has generated a LOAD_DEREF bytecode
         # then we do have the name defined in a parent scope. However, in the
         # interests of not crashing the indexer, fall back to the current scope.
         # TODO(mdemello): We need error logs.
         pass
     ref = self.make_ref(node, **kwargs)
     self.refs.append(ref)
     return ref
Exemple #6
0
    def make_def(self, node, **kwargs):
        """Make a definition from a node."""

        if isinstance(node, self._ast.Name):
            t = node_utils.typename(node.ctx)
        elif isinstance(node, self._ast.arg):
            t = "Param"
        else:
            t = node_utils.typename(node)
        args = {
            "name": node_utils.get_name(node, self._ast),
            "scope": self.scope_id(),
            "typ": t,
            "data": None,
            "target": None,
            "doc": None,
        }
        args.update(kwargs)
        defn = Definition(**args)
        line, col = self._get_location(node, args)
        assert line is not None
        defloc = DefLocation(defn.id, source.Location(line, col))
        return (defn, defloc)