示例#1
0
 def _get_match_location(self, node, name=None):
     loc = source.Location(node.lineno, node.col_offset)
     if not name:
         return loc
     if isinstance(node, (self._ast.Import, self._ast.ImportFrom)):
         # Search for imported module names
         m = re.search("[ ,]" + name + r"\b", self.source.line(node.lineno))
         if m is not None:
             c, _ = m.span()
             return source.Location(node.lineno, c + 1)
     elif isinstance(node, self._ast.Attribute):
         attr_loc, _ = self.source.get_attr_location(name, loc)
         return attr_loc
     return loc
示例#2
0
 def _get_match_location(self, node, name=None):
   loc = source.Location(node.lineno, node.col_offset)
   if not name:
     return loc
   if isinstance(node, (self._ast.Import, self._ast.ImportFrom)):
     # Search for imported module names
     text = self.source.line(node.lineno)
     c = text.find(" " + name)
     if c == -1:
       c = text.find("," + name)
     if c != -1:
       return source.Location(node.lineno, c + 1)
   elif isinstance(node, self._ast.Attribute):
     attr_loc, _ = self.source.get_attr_location(name, loc)
     return attr_loc
   return loc
示例#3
0
  def test_get_offset_multibyte(self):
    # With single-byte characters
    src = source.Code("""
      # coding=utf-8
      line1 # a
      line2
    """, [], _FakeTrace, "")
    self.assertEqual(src.get_offset(source.Location(4, 3)), 41)

    # With a multibyte character the byte offset should change
    src = source.Code("""
      # coding=utf-8
      line1 # ツ
      line2
    """, [], _FakeTrace, "")
    self.assertEqual(src.get_offset(source.Location(4, 3)), 43)
示例#4
0
文件: indexer.py 项目: liux-n/pytype
  def process_import(self, node):
    """Common code for Import and ImportFrom."""

    for alias, (loc, (op, symbol, data)) in zip(node.names, self.match(node)):
      # If an import is aliased, match() returns only the symbol/loc of
      # the alias, whereas the indexer also needs access to the unaliased
      # name in order to reference the imported module.
      defn = None  # type: Optional[Definition]
      if alias.asname:
        defn = self.add_local_def(
            node, name=symbol, target=alias.name, data=data)
        defloc = self.locs[defn.id].pop()
        self.locs[defn.id].append(DefLocation(defloc.def_id, loc))

        # Shift symbol/loc back to the unaliased name.
        symbol = alias.name
        m = re.search("[ ,]" + symbol + r"\b", self.source.line(loc.line))
        assert m is not None
        c, _ = m.span()
        loc = source.Location(loc.line, c + 1)

      try:
        [imported] = _unwrap(data)
      except ValueError:
        continue  # Unresolved import.

      if op == "STORE_NAME":
        # for |import x.y as z| or |from x import y as z| we want {z: x.y}
        self.add_local_ref(node, name=symbol, data=data, location=loc)
        if not isinstance(imported, abstract.Module):
          # Make the from-imported symbol available in the current namespace.
          remote = Remote(imported.module, name=symbol, resolved=True)
          if defn:
            self.aliases[defn.id] = remote
          self.current_env[symbol] = remote
          self.typemap[remote.id] = [imported]
          continue

        if defn:
          remote = Remote(imported.full_name, IMPORT_FILE_MARKER, resolved=True)
          self.aliases[defn.id] = remote
          self.modules[defn.id] = imported.full_name
        else:
          self.modules[self.scope_id() + "." + symbol] = imported.full_name
      elif op == "IMPORT_NAME":
        # |import x.y| puts both {x: x} and {x.y: x.y} in modules
        self.add_local_ref(node, name=symbol, data=data, location=loc)
        # TODO(slebedev): Reference every import path component.
        # For example here
        #
        #   from foo.bar import boo
        #   import foo.bar.boo
        #
        # we should reference both foo and foo.bar (in addition to foo.bar.boo).
        for mod in module_utils.get_all_prefixes(symbol):
          self.modules[self.scope_id() + "." + mod] = mod
示例#5
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)
示例#6
0
    def process_import(self, node):
        """Common code for Import and ImportFrom."""

        # Only record modules that pytype has resolved in self.modules
        def is_resolved(data):
            return data and isinstance(data[0], abstract.Module)

        def add_import_ref(name, data, loc):
            self.add_global_ref(node,
                                name=name,
                                data=data,
                                location=loc,
                                typ="Import")

        for loc, (op, symbol, data) in self.match(node):
            d = self.add_local_def(node, name=symbol)
            defloc = self.locs[d.id][-1]

            # tweak the definition location slightly
            line, _ = loc
            text = self.source.line(line)
            c = text.find("import ")
            new_loc = source.Location(line, c) if c > -1 else loc
            self.locs[d.id][-1] = DefLocation(defloc.def_id, new_loc)

            if not is_resolved(_unwrap(data)):
                continue
            elif op == "STORE_NAME":
                # for |import x.y as z| or |from x import y as z| we want {z: x.y}
                self.modules[d.id] = _unwrap(data)[0].full_name
                add_import_ref(name=symbol, data=data, loc=loc)
            elif op == "IMPORT_NAME":
                # |import x.y| puts both {x: x} and {x.y: x.y} in modules
                add_import_ref(name=symbol, data=data, loc=loc)
                for mod in module_utils.get_all_prefixes(symbol):
                    # TODO(mdemello): Create references for every element.
                    self.modules[d.scope + "." + mod] = mod
示例#7
0
 def test_one_line(self):
     src = source.Code("foo.bar", [], _FakeTrace, "")
     self.assertEqual(
         src.get_attr_location("foo.bar", source.Location(1, 0)),
         (source.Location(1, 4), 3))
示例#8
0
 def test_find_first_text(self):
     src = source.Code("line1\nline2\nline3", [], _FakeTrace, "")
     self.assertEqual(src.find_first_text(2, 5, "line"),
                      source.Location(2, 0))
     self.assertIsNone(src.find_first_text(2, 5, "duck"))
示例#9
0
 def test_get_offset(self):
     src = source.Code("line1\nline2", [], _FakeTrace, "")
     self.assertEqual(src.get_offset(source.Location(2, 3)), 9)
示例#10
0
 def test_not_found(self):
     src = source.Code("foo.bar", [], _FakeTrace, "")
     self.assertEqual(
         src.get_attr_location("foo.baz", source.Location(1, 0)),
         (source.Location(1, 0), 7))
示例#11
0
 def test_dot_attr(self):
     src = source.Code("foo\n.bar", [], _FakeTrace, "")
     self.assertEqual(
         src.get_attr_location("foo.bar", source.Location(1, 0)),
         (source.Location(2, 1), 3))
示例#12
0
def get_location(node):
    # TODO(mdemello): The column offset for nodes like "class A" needs to be
    # adjusted to the start of the symbol.
    return source.Location(node.lineno, node.col_offset)