git / moonbite-core / src/crc32c/.ycm_extra_conf.py · raw

# Copyright 2017 The CRC32C Authors. All rights reserved.# Use of this source code is governed by a BSD-style license that can be# found in the LICENSE file."""YouCompleteMe configuration that interprets a .clang_complete file.This module implementes the YouCompleteMe configuration API documented at:https://github.com/Valloric/ycmd#ycm_extra_confpy-specificationThe implementation loads and processes a .clang_complete file, documented at:https://github.com/Rip-Rip/clang_complete/blob/master/README.md"""import os# Flags added to the list in .clang_complete.BASE_FLAGS = [    '-Werror',  # Unlike clang_complete, YCM can also be used as a linter.    '-DUSE_CLANG_COMPLETER',  # YCM needs this.    '-xc++',  # YCM needs this to avoid compiling headers as C code.]# Clang flags that take in paths.# See https://clang.llvm.org/docs/ClangCommandLineReference.htmlPATH_FLAGS = [    '-isystem',    '-I',    '-iquote',    '--sysroot=']def DirectoryOfThisScript():  """Returns the absolute path to the directory containing this script."""  return os.path.dirname(os.path.abspath(__file__))def MakeRelativePathsInFlagsAbsolute(flags, build_root):  """Expands relative paths in a list of Clang command-line flags.  Args:    flags: The list of flags passed to Clang.    build_root: The current directory when running the Clang compiler. Should be        an absolute path.  Returns:    A list of flags with relative paths replaced by absolute paths.  """  new_flags = []  make_next_absolute = False  for flag in flags:    new_flag = flag    if make_next_absolute:      make_next_absolute = False      if not flag.startswith('/'):        new_flag = os.path.join(build_root, flag)    for path_flag in PATH_FLAGS:      if flag == path_flag:        make_next_absolute = True        break      if flag.startswith(path_flag):        path = flag[len(path_flag):]        new_flag = path_flag + os.path.join(build_root, path)        break    if new_flag:      new_flags.append(new_flag)  return new_flagsdef FindNearest(target, path, build_root):  """Looks for a file with a specific name closest to a project path.  This is similar to the logic used by a version-control system (like git) to  find its configuration directory (.git) based on the current directory when a  command is invoked.  Args:    target: The file name to search for.    path: The directory where the search starts. The search will explore the        given directory's ascendants using the parent relationship. Should be an        absolute path.    build_root: A directory that acts as a fence for the search. If the search        reaches this directory, it will not advance to its parent. Should be an        absolute path.  Returns:    The path to a file with the desired name. None if the search failed.  """  candidate = os.path.join(path, target)  if os.path.isfile(candidate):    return candidate  if path == build_root:    return None  parent = os.path.dirname(path)  if parent == path:    return None  return FindNearest(target, parent, build_root)def FlagsForClangComplete(file_path, build_root):  """Reads the .clang_complete flags for a source file.  Args:    file_path: The path to the source file. Should be inside the project. Used      to locate the relevant .clang_complete file.    build_root: The current directory when running the Clang compiler for this        file. Should be an absolute path.  Returns:    A list of strings, where each element is a Clang command-line flag.  """  clang_complete_path = FindNearest('.clang_complete', file_path, build_root)  if clang_complete_path is None:    return None  clang_complete_flags = open(clang_complete_path, 'r').read().splitlines()  return clang_complete_flagsdef FlagsForFile(filename, **kwargs):  """Implements the YouCompleteMe API."""  # kwargs can be used to pass 'client_data' to the YCM configuration. This  # configuration script does not need any extra information, so  # pylint: disable=unused-argument  build_root = DirectoryOfThisScript()  file_path = os.path.realpath(filename)  flags = BASE_FLAGS  clang_flags = FlagsForClangComplete(file_path, build_root)  if clang_flags:    flags += clang_flags  final_flags = MakeRelativePathsInFlagsAbsolute(flags, build_root)  return {'flags': final_flags}