Пример #1
0
def generateDoxygenForSourceLocation(line, col):
  filename = vim.current.buffer.name

  index = Index.create()
  tu = index.parse(filename, vim.eval("g:clang_doxygen_clang_args"), [(filename, "\n".join(vim.current.buffer[:]))])

  # Skip whitespace at beginning of line
  indent = re.match(r'^\s*', vim.current.buffer[line - 1]).span()[1]
  col = max(col, indent + 1)

  c = Cursor.from_location(tu, SourceLocation.from_position(tu, File.from_name(tu, filename), line, col))

  # If there is no declaration at the source location try to find the nearest one.
  while c is not None:
    # If cursor is on a TypeRef in a FunctionTemplate, manually go backward in the source.
    if c.kind == CursorKind.TYPE_REF:
      pLine, pCol = previousSourceLocation(c.extent.start.line, c.extent.start.column)
      c = Cursor.from_location(tu, SourceLocation.from_position(tu, File.from_name(tu, filename), pLine, pCol))
      continue
    # If cursor is on a NamespaceRef, manually go forward in the source.
    elif c.kind == CursorKind.NAMESPACE_REF:
      nLine, nCol = nextSourceLocation(c.extent.end.line, c.extent.end.column)
      c = Cursor.from_location(tu, SourceLocation.from_position(tu, File.from_name(tu, filename), nLine, nCol))
      continue
    elif c.kind == CursorKind.FUNCTION_DECL:
      return handleFunctionDecl(c)
    elif c.kind == CursorKind.CXX_METHOD:
      return handleFunctionDecl(c)
    elif c.kind == CursorKind.CONSTRUCTOR:
      return handleFunctionDecl(c)
    elif c.kind == CursorKind.DESTRUCTOR:
      return handleFunctionDecl(c)
    elif c.kind == CursorKind.FUNCTION_TEMPLATE:
      return handleFunctionTemplate(c)
    elif c.kind == CursorKind.CLASS_DECL:
      return handleClassDecl(c)
    elif c.kind == CursorKind.CLASS_TEMPLATE:
      return handleClassDecl(c)
    elif c.kind == CursorKind.OBJC_INSTANCE_METHOD_DECL:
      return handleFunctionDecl(c)
    elif c.kind == CursorKind.OBJC_INTERFACE_DECL:
      return handleClassDecl(c)
    elif c.kind == CursorKind.OBJC_CATEGORY_DECL:
      return handleClassDecl(c)
    elif c.kind == CursorKind.OBJC_IMPLEMENTATION_DECL:
      return handleClassDecl(c)
    # Cursor is not on a supported type, go to the lexical parent
    else:
      c = c.lexical_parent

  if c is None:
    print "Error: No supported declaration found at %s:%i,%i.\n" % (filename, line, col)
    return (None, None)
Пример #2
0
def test_file():
  index = Index.create()
  tu = index.parse('t.c', unsaved_files = [('t.c', "")])
  file = File.from_name(tu, "t.c")
  assert str(file) == "t.c"
  assert file.name == "t.c"
  assert repr(file) == "<File: t.c>"
Пример #3
0
def gotoDeclaration(preview=True):
    global debug
    debug = int(vim.eval("g:clang_debug")) == 1
    params = getCompileParams(vim.current.buffer.name)
    line, col = vim.current.window.cursor
    timer = CodeCompleteTimer(debug, vim.current.buffer.name, line, col,
                              params)

    with libclangLock:
        tu = getCurrentTranslationUnit(params['args'],
                                       getCurrentFile(),
                                       vim.current.buffer.name,
                                       timer,
                                       update=True)
        if tu is None:
            print("Couldn't get the TranslationUnit")
            return

        f = File.from_name(tu, vim.current.buffer.name)
        loc = SourceLocation.from_position(tu, f, line, col + 1)
        cursor = Cursor.from_location(tu, loc)
        defs = [cursor.get_definition(), cursor.referenced]

        for d in defs:
            if d is not None and loc != d.location:
                loc = d.location
                if loc.file is not None:
                    jumpToLocation(loc.file.name, loc.line, loc.column,
                                   preview)
                break

    timer.finish()
Пример #4
0
    def test_extent(self):
        tu = get_tu(baseInput)
        one = get_cursor(tu, 'one')
        two = get_cursor(tu, 'two')

        self.assert_location(one.extent.start, line=1, column=1, offset=0)
        self.assert_location(one.extent.end, line=1, column=8, offset=7)
        self.assertEqual(
            baseInput[one.extent.start.offset:one.extent.end.offset],
            "int one")

        self.assert_location(two.extent.start, line=2, column=1, offset=9)
        self.assert_location(two.extent.end, line=2, column=8, offset=16)
        self.assertEqual(
            baseInput[two.extent.start.offset:two.extent.end.offset],
            "int two")

        file = File.from_name(tu, 't.c')
        location1 = SourceLocation.from_position(tu, file, 1, 1)
        location2 = SourceLocation.from_position(tu, file, 1, 8)

        range1 = SourceRange.from_locations(location1, location2)
        range2 = SourceRange.from_locations(location1, location2)
        self.assertEqual(range1, range2)

        location3 = SourceLocation.from_position(tu, file, 1, 6)
        range3 = SourceRange.from_locations(location1, location3)
        self.assertNotEqual(range1, range3)
Пример #5
0
 def test_file(self):
     index = Index.create()
     tu = index.parse('t.c', unsaved_files=[('t.c', "")])
     file = File.from_name(tu, "t.c")
     self.assertEqual(str(file), "t.c")
     self.assertEqual(file.name, "t.c")
     self.assertEqual(repr(file), "<File: t.c>")
Пример #6
0
    def get_usr_under_cursor(self, file_name, line, col):
        with self.c_parse_lock:
            if file_name not in self.current_file_tus:
                return ""
            tu = self.current_file_tus[file_name]
        f = File.from_name(tu, file_name)
        loc = SourceLocation.from_position(tu, f, int(line), int(col))
        cursor = Cursor.from_location(tu, loc)

        while cursor is not None and (not cursor.referenced
                                      or not cursor.referenced.get_usr()):
            nextCursor = cursor.lexical_parent
            if nextCursor is not None and nextCursor == cursor:
                return ""
            cursor = nextCursor
        if cursor is None:
            return ""

        cursor = cursor.referenced
        if cursor is None:
            return ""

        return {
            'usr': cursor.get_usr(),
            'file': str(cursor.location.file),
            'line': cursor.location.line,
            'column': cursor.location.column
        }
Пример #7
0
def gotoDeclaration(preview=True):
  global debug
  debug = int(vim.eval("g:clang_debug")) == 1
  params = getCompileParams(vim.current.buffer.name)
  line, col = vim.current.window.cursor
  timer = CodeCompleteTimer(debug, vim.current.buffer.name, line, col, params)

  with libclangLock:
    tu = getCurrentTranslationUnit(params['args'], getCurrentFile(),
                                   vim.current.buffer.name, timer,
                                   update = True)
    if tu is None:
      print("Couldn't get the TranslationUnit")
      return

    f = File.from_name(tu, vim.current.buffer.name)
    loc = SourceLocation.from_position(tu, f, line, col + 1)
    cursor = Cursor.from_location(tu, loc)
    defs = [cursor.get_definition(), cursor.referenced]

    for d in defs:
      if d is not None and loc != d.location:
        loc = d.location
        if loc.file is not None:
          jumpToLocation(loc.file.name, loc.line, loc.column, preview)
        break

  timer.finish()
Пример #8
0
 def test_file(self):
     index = Index.create()
     tu = index.parse('t.c', unsaved_files = [('t.c', "")])
     file = File.from_name(tu, "t.c")
     self.assertEqual(str(file), "t.c")
     self.assertEqual(file.name, "t.c")
     self.assertEqual(repr(file), "<File: t.c>")
Пример #9
0
def test_file():
  index = Index.create()
  tu = index.parse('t.c', unsaved_files = [('t.c', "")])
  file = File.from_name(tu, "t.c")
  assert str(file) == "t.c"
  assert file.name == "t.c"
  assert repr(file) == "<File: t.c>"
Пример #10
0
def test_extent():
    tu = get_tu(baseInput)
    one = get_cursor(tu, 'one')
    two = get_cursor(tu, 'two')

    assert_location(one.extent.start, line=1, column=1, offset=0)
    assert_location(one.extent.end, line=1, column=8, offset=7)
    assert baseInput[one.extent.start.offset:one.extent.end.
                     offset] == "int one"

    assert_location(two.extent.start, line=2, column=1, offset=9)
    assert_location(two.extent.end, line=2, column=8, offset=16)
    assert baseInput[two.extent.start.offset:two.extent.end.
                     offset] == "int two"

    file = File.from_name(tu, 't.c')
    location1 = SourceLocation.from_position(tu, file, 1, 1)
    location2 = SourceLocation.from_position(tu, file, 1, 8)

    range1 = SourceRange.from_locations(location1, location2)
    range2 = SourceRange.from_locations(location1, location2)
    assert range1 == range2

    location3 = SourceLocation.from_position(tu, file, 1, 6)
    range3 = SourceRange.from_locations(location1, location3)
    assert range1 != range3
Пример #11
0
def test_location():
    tu = get_tu(baseInput)
    one = get_cursor(tu, 'one')
    two = get_cursor(tu, 'two')

    assert one is not None
    assert two is not None

    assert_location(one.location, line=1, column=5, offset=4)
    assert_location(two.location, line=2, column=5, offset=13)

    # adding a linebreak at top should keep columns same
    tu = get_tu('\n' + baseInput)
    one = get_cursor(tu, 'one')
    two = get_cursor(tu, 'two')

    assert one is not None
    assert two is not None

    assert_location(one.location, line=2, column=5, offset=5)
    assert_location(two.location, line=3, column=5, offset=14)

    # adding a space should affect column on first line only
    tu = get_tu(' ' + baseInput)
    one = get_cursor(tu, 'one')
    two = get_cursor(tu, 'two')

    assert_location(one.location, line=1, column=6, offset=5)
    assert_location(two.location, line=2, column=5, offset=14)

    # define the expected location ourselves and see if it matches
    # the returned location
    tu = get_tu(baseInput)

    file = File.from_name(tu, 't.c')
    location = SourceLocation.from_position(tu, file, 1, 5)
    cursor = Cursor.from_location(tu, location)

    one = get_cursor(tu, 'one')
    assert one is not None
    assert one == cursor

    # Ensure locations referring to the same entity are equivalent.
    location2 = SourceLocation.from_position(tu, file, 1, 5)
    assert location == location2
    location3 = SourceLocation.from_position(tu, file, 1, 4)
    assert location2 != location3

    offset_location = SourceLocation.from_offset(tu, file, 5)
    cursor = Cursor.from_location(tu, offset_location)
    verified = False
    for n in [n for n in tu.cursor.get_children() if n.spelling == 'one']:
        assert n == cursor
        verified = True

    assert verified
Пример #12
0
def test_location():
    tu = get_tu(baseInput)
    one = get_cursor(tu, 'one')
    two = get_cursor(tu, 'two')

    assert one is not None
    assert two is not None

    assert_location(one.location, line=1, column=5, offset=4)
    assert_location(two.location, line=2, column=5, offset=13)

    # adding a linebreak at top should keep columns same
    tu = get_tu('\n' + baseInput)
    one = get_cursor(tu, 'one')
    two = get_cursor(tu, 'two')

    assert one is not None
    assert two is not None

    assert_location(one.location, line=2, column=5, offset=5)
    assert_location(two.location, line=3, column=5, offset=14)

    # adding a space should affect column on first line only
    tu = get_tu(' ' + baseInput)
    one = get_cursor(tu, 'one')
    two = get_cursor(tu, 'two')

    assert_location(one.location, line=1, column=6, offset=5)
    assert_location(two.location, line=2, column=5, offset=14)

    # define the expected location ourselves and see if it matches
    # the returned location
    tu = get_tu(baseInput)

    file = File.from_name(tu, 't.c')
    location = SourceLocation.from_position(tu, file, 1, 5)
    cursor = Cursor.from_location(tu, location)

    one = get_cursor(tu, 'one')
    assert one is not None
    assert one == cursor

    # Ensure locations referring to the same entity are equivalent.
    location2 = SourceLocation.from_position(tu, file, 1, 5)
    assert location == location2
    location3 = SourceLocation.from_position(tu, file, 1, 4)
    assert location2 != location3

    offset_location = SourceLocation.from_offset(tu, file, 5)
    cursor = Cursor.from_location(tu, offset_location)
    verified = False
    for n in [n for n in tu.cursor.get_children() if n.spelling == 'one']:
        assert n == cursor
        verified = True

    assert verified
Пример #13
0
def GetCurrentUsrCursor(tu):
    line, col = vim.current.window.cursor
    col = col + 1
    f = File.from_name(tu, vim.current.buffer.name)
    loc = SourceLocation.from_position(tu, f, line, col)
    cursor = Cursor.from_location(tu, loc)

    while cursor is not None and (not cursor.referenced or not cursor.referenced.get_usr()):
        nextCursor = cursor.lexical_parent
        if nextCursor is not None and nextCursor == cursor:
            return None
        cursor = nextCursor
    if cursor is None:
        return None
    return cursor.referenced
Пример #14
0
    def find_declaration(self, data, lines):
        self.join_queue()

        context = data['context']
        src = self.get_src("\n".join(lines), context)
        filepath = context['filepath']
        bcol = context['bcol']
        lnum = context['lnum']

        args, directory = self.get_args_dir(data)

        tu = self.get_tu(filepath, args, directory, src)

        f = File.from_name(tu, filepath)
        location = SourceLocation.from_position(tu, f, lnum, bcol)
        cursor = Cursor.from_location(tu, location)

        defs = [cursor.get_definition(), cursor.referenced]
        for d in defs:
            if d is None:
                logger.info("d None")
                continue

            d_loc = d.location
            if d_loc.file is None:
                logger.info("location.file None")
                continue

            ret = {}
            ret['file'] = d_loc.file.name
            ret['lnum'] = d_loc.line
            ret['bcol'] = d_loc.column
            return ret

        # we failed finding the declaration, maybe there's some syntax error
        # stopping us. Report it to the user.
        logger.info('reading Diagnostic for this tu, args: %s', args)
        for diag in tu.diagnostics:
            # type: Diagnostic
            if diag.severity < diag.Error:
                pass
            self.nvim.call('ncm2_pyclang#error', diag.format())
        return {}
Пример #15
0
    def get_usr_under_cursor(self, file_name, line, col):
        with self.c_parse_lock:
            if file_name not in self.current_file_tus:
                return ""
            tu = self.current_file_tus[file_name]
        f = File.from_name(tu, file_name)
        loc = SourceLocation.from_position(tu, f, int(line), int(col))
        cursor = Cursor.from_location(tu, loc)

        while cursor is not None and (not cursor.referenced or not cursor.referenced.get_usr()):
            nextCursor = cursor.lexical_parent
            if nextCursor is not None and nextCursor == cursor:
                return ""
            cursor = nextCursor
        if cursor is None:
            return ""

        cursor = cursor.referenced
        if cursor is None:
            return ""

        return {'usr': cursor.get_usr(), 'file': str(cursor.location.file), 'line': cursor.location.line, 'column': cursor.location.column}
Пример #16
0
  def gotoDeclaration(self, preview=True):
    params = self.getCompileParams(self.vim.current.buffer.name)
    line, col = self.vim.current.window.cursor

    tu = self.getCurrentTranslationUnit(params['args'], self.getCurrentFile(),
                                   self.vim.current.buffer.name,
                                   update = True)
    if tu is None:
      print("Couldn't get the TranslationUnit")
      return

    f      = File.from_name(tu, self.vim.current.buffer.name)
    loc    = SourceLocation.from_position(tu, f, line, col + 1)
    cursor = Cursor.from_location(tu, loc)
    defs   = [cursor.get_definition(), cursor.referenced]

    for d in defs:
      if d is not None and loc != d.location:
        loc = d.location
        if loc.file is not None:
          self.jumpToLocation(loc.file.name, loc.line, loc.column, preview)
        break
Пример #17
0
def test_location():
    index = Index.create()
    tu = index.parse('t.c', unsaved_files = [('t.c',baseInput)])

    for n in tu.cursor.get_children():
        if n.spelling == 'one':
            assert_location(n.location,line=1,column=5,offset=4)
        if n.spelling == 'two':
            assert_location(n.location,line=2,column=5,offset=13)

    # adding a linebreak at top should keep columns same
    tu = index.parse('t.c', unsaved_files = [('t.c',"\n"+baseInput)])

    for n in tu.cursor.get_children():
        if n.spelling == 'one':
            assert_location(n.location,line=2,column=5,offset=5)
        if n.spelling == 'two':
            assert_location(n.location,line=3,column=5,offset=14)

    # adding a space should affect column on first line only
    tu = index.parse('t.c', unsaved_files = [('t.c'," "+baseInput)])

    for n in tu.cursor.get_children():
        if n.spelling == 'one':
            assert_location(n.location,line=1,column=6,offset=5)
        if n.spelling == 'two':
            assert_location(n.location,line=2,column=5,offset=14)

    # define the expected location ourselves and see if it matches
    # the returned location
    tu = index.parse('t.c', unsaved_files = [('t.c',baseInput)])

    file = File.from_name(tu, 't.c')
    location = SourceLocation.from_position(tu, file, 1, 5)
    cursor = Cursor.from_location(tu, location)

    for n in tu.cursor.get_children():
        if n.spelling == 'one':
            assert n == cursor
Пример #18
0
    def test_extent(self):
        tu = get_tu(baseInput)
        one = get_cursor(tu, 'one')
        two = get_cursor(tu, 'two')

        self.assert_location(one.extent.start,line=1,column=1,offset=0)
        self.assert_location(one.extent.end,line=1,column=8,offset=7)
        self.assertEqual(baseInput[one.extent.start.offset:one.extent.end.offset], "int one")

        self.assert_location(two.extent.start,line=2,column=1,offset=9)
        self.assert_location(two.extent.end,line=2,column=8,offset=16)
        self.assertEqual(baseInput[two.extent.start.offset:two.extent.end.offset], "int two")

        file = File.from_name(tu, 't.c')
        location1 = SourceLocation.from_position(tu, file, 1, 1)
        location2 = SourceLocation.from_position(tu, file, 1, 8)

        range1 = SourceRange.from_locations(location1, location2)
        range2 = SourceRange.from_locations(location1, location2)
        self.assertEqual(range1, range2)

        location3 = SourceLocation.from_position(tu, file, 1, 6)
        range3 = SourceRange.from_locations(location1, location3)
        self.assertNotEqual(range1, range3)
Пример #19
0
def test_extent():
    tu = get_tu(baseInput)
    one = get_cursor(tu, 'one')
    two = get_cursor(tu, 'two')

    assert_location(one.extent.start, line=1, column=1, offset=0)
    assert_location(one.extent.end, line=1, column=8, offset=7)
    assert baseInput[one.extent.start.offset:one.extent.end.offset] == "int one"

    assert_location(two.extent.start, line=2, column=1, offset=9)
    assert_location(two.extent.end, line=2, column=8, offset=16)
    assert baseInput[two.extent.start.offset:two.extent.end.offset] == "int two"

    file = File.from_name(tu, 't.c')
    location1 = SourceLocation.from_position(tu, file, 1, 1)
    location2 = SourceLocation.from_position(tu, file, 1, 8)

    range1 = SourceRange.from_locations(location1, location2)
    range2 = SourceRange.from_locations(location1, location2)
    assert range1 == range2

    location3 = SourceLocation.from_position(tu, file, 1, 6)
    range3 = SourceRange.from_locations(location1, location3)
    assert range1 != range3
Пример #20
0
def get_static_locations(dynamic_locations, clang_include_paths):
    """
    Get locations for certain constructs which are only available statically.
    - Variable declarations without any executable code "int i;"
    - Case statements "case foo:"
    - Default statements "default: "
    """
    static_locations = []

    def ancestor_node(n):
        """
        Get the nearest significant ancestor.
        """
        if n.kind == CursorKind.FUNCTION_DECL:
            return n
        else:
            if n.semantic_parent is None:
                return n
            else:
                return ancestor_node(n.semantic_parent)

    def good(n):
        """
        Node should be added to the trace.
        """
        if n.kind in (CursorKind.VAR_DECL, CursorKind.CASE_STMT,
                      CursorKind.DEFAULT_STMT):
            return True
        else:
            return False

    filepaths = defaultdict(list)
    for l in dynamic_locations:
        filepaths[l.filepath].append(l)
    for filepath, locations in filepaths.items():
        log.debug(
            f'Parsing source file {filepath} with args {clang_include_paths}')
        root = nodeutils.parse(filepath, clang_include_paths)
        ancestors = []
        file = File.from_name(root.translation_unit, filepath)
        for l in locations:
            source_location = SourceLocation.from_position(
                root.translation_unit, file, l.lineno, l.column)
            node = Cursor.from_location(root.translation_unit, source_location)
            l.node = node
            if node.kind.is_invalid():
                continue
            ancestor = ancestor_node(node)
            if ancestor not in ancestors:
                log.debug(
                    f'node {nodeutils.pp(node)} has ancestor {nodeutils.pp(ancestor)}'
                )
                ancestors.append(ancestor)
        for a in ancestors:
            if a.kind.is_translation_unit():
                continue  # Do not include global constructs
            else:
                nodes = nodeutils.find(a, good)
                locations = [
                    Location(n.location.file.name, n.location.line,
                             n.location.column, n) for n in nodes
                ]
                for l in locations:
                    log.debug(f'static location {l}')
                static_locations += locations

    return static_locations