Esempio n. 1
0
    def _GetSemanticInfo(
            self,
            request_data,
            func,
            response_builder=responses.BuildDisplayMessageResponse,
            reparse=True):
        flags, filename = self._FlagsForRequest(request_data)
        if not flags:
            raise ValueError(NO_COMPILE_FLAGS_MESSAGE)

        if self._completer.UpdatingTranslationUnit(
                ToCppStringCompatible(filename)):
            raise RuntimeError(PARSING_FILE_MESSAGE)

        files = self.GetUnsavedFilesVector(request_data)
        line = request_data['line_num']
        column = request_data['column_num']

        message = getattr(self._completer, func)(
            ToCppStringCompatible(filename),
            ToCppStringCompatible(request_data['filepath']), line, column,
            files, flags, reparse)

        if not message:
            message = "No semantic information available"

        return response_builder(message)
Esempio n. 2
0
  def ComputeCandidatesInner( self, request_data ):
    filename = request_data[ 'filepath' ]
    if not filename:
      return

    if self._completer.UpdatingTranslationUnit(
        ToCppStringCompatible( filename ) ):
      raise RuntimeError( PARSING_FILE_MESSAGE )

    flags = self._FlagsForRequest( request_data )
    if not flags:
      raise RuntimeError( NO_COMPILE_FLAGS_MESSAGE )

    files = self.GetUnsavedFilesVector( request_data )
    line = request_data[ 'line_num' ]
    column = request_data[ 'start_column' ]
    with self._files_being_compiled.GetExclusive( filename ):
      results = self._completer.CandidatesForLocationInFile(
          ToCppStringCompatible( filename ),
          line,
          column,
          files,
          flags )

    if not results:
      raise RuntimeError( NO_COMPLETIONS_MESSAGE )

    return [ ConvertCompletionData( x ) for x in results ]
Esempio n. 3
0
  def _FixIt( self, request_data ):
    flags, filename = self._FlagsForRequest( request_data )
    if not flags:
      raise ValueError( NO_COMPILE_FLAGS_MESSAGE )

    if self._completer.UpdatingTranslationUnit(
        ToCppStringCompatible( filename ) ):
      raise RuntimeError( PARSING_FILE_MESSAGE )

    files = self.GetUnsavedFilesVector( request_data )
    line = request_data[ 'line_num' ]
    column = request_data[ 'column_num' ]

    fixits = getattr( self._completer, "GetFixItsForLocationInFile" )(
        ToCppStringCompatible( filename ),
        ToCppStringCompatible( request_data[ 'filepath' ] ),
        line,
        column,
        files,
        flags,
        True )

    # don't raise an error if not fixits: - leave that to the client to respond
    # in a nice way

    return responses.BuildFixItResponse( fixits )
    def _AddIdentifiersFromSyntax(self, keyword_list, filetype):
        keyword_vector = ycm_core.StringVector()
        for keyword in keyword_list:
            keyword_vector.append(ToCppStringCompatible(keyword))

        filepath = SYNTAX_FILENAME + filetype
        self._completer.AddIdentifiersToDatabase(
            keyword_vector, ToCppStringCompatible(filetype),
            ToCppStringCompatible(filepath))
Esempio n. 5
0
    def _LocationForGoTo(self, goto_function, request_data, reparse=True):
        flags, filename = self._FlagsForRequest(request_data)
        if not flags:
            raise ValueError(NO_COMPILE_FLAGS_MESSAGE)

        files = self.GetUnsavedFilesVector(request_data)
        line = request_data['line_num']
        column = request_data['column_num']
        return getattr(self._completer, goto_function)(
            ToCppStringCompatible(filename),
            ToCppStringCompatible(request_data['filepath']), line, column,
            files, flags, reparse)
Esempio n. 6
0
    def _AddIdentifier(self, identifier, request_data):
        filetype = request_data['first_filetype']
        filepath = request_data['filepath']

        if not filetype or not filepath or not identifier:
            return

        vector = ycm_core.StringVector()
        vector.append(ToCppStringCompatible(identifier))
        LOGGER.info('Adding ONE buffer identifier for file: %s', filepath)
        self._completer.AddIdentifiersToDatabase(
            vector, ToCppStringCompatible(filetype),
            ToCppStringCompatible(filepath))
Esempio n. 7
0
def FilterAndSortCandidatesWrap(candidates, sort_property, query):
    from ycm_core import FilterAndSortCandidates

    # The c++ interface we use only understands the (*native*) 'str' type (i.e.
    # not the 'str' type from python-future. If we pass it a 'unicode' or
    # 'bytes' instance then various things blow up, such as converting to
    # std::string. Therefore all strings passed into the c++ API must pass through
    # ToCppStringCompatible (or more strictly all strings which the C++ code
    # needs to use and convert. In this case, just the insertion text property)
    # For efficiency, the conversion of the insertion text property is done in the
    # C++ layer.
    return FilterAndSortCandidates(candidates,
                                   ToCppStringCompatible(sort_property),
                                   ToCppStringCompatible(query))
    def _AddBufferIdentifiers(self, request_data):
        filetype = request_data['first_filetype']
        filepath = request_data['filepath']

        if not filetype or not filepath:
            return

        collect_from_comments_and_strings = bool(
            self.user_options['collect_identifiers_from_comments_and_strings'])
        text = request_data['file_data'][filepath]['contents']
        self._logger.info('Adding buffer identifiers for file: %s', filepath)
        self._completer.ClearForFileAndAddIdentifiersToDatabase(
            _IdentifiersFromBuffer(text, filetype,
                                   collect_from_comments_and_strings),
            ToCppStringCompatible(filetype), ToCppStringCompatible(filepath))
Esempio n. 9
0
def FilterAndSortCandidatesWrap(candidates, sort_property, query,
                                max_candidates):
    from ycm_core import FilterAndSortCandidates

    # The c++ interface we use only understands the 'str' type. If we pass it a
    # 'unicode' or 'bytes' instance then various things blow up, such as
    # converting to std::string. Therefore all strings passed into the c++ API
    # must pass through ToCppStringCompatible (or more strictly all strings which
    # the C++ code needs to use and convert. In this case, just the insertion
    # text property) For efficiency, the conversion of the insertion text
    # property is done in the C++ layer.
    return FilterAndSortCandidates(candidates,
                                   ToCppStringCompatible(sort_property),
                                   ToCppStringCompatible(query),
                                   max_candidates)
Esempio n. 10
0
def PrepareFlagsForClang(flags,
                         filename,
                         add_extra_clang_flags=True,
                         enable_windows_style_flags=False):
    flags = _AddLanguageFlagWhenAppropriate(flags, enable_windows_style_flags)
    flags = _RemoveXclangFlags(flags)
    flags = _RemoveUnusedFlags(flags, filename, enable_windows_style_flags)
    if add_extra_clang_flags:
        # This flag tells libclang where to find the builtin includes.
        flags.append('-resource-dir=' + CLANG_RESOURCE_DIR)
        # On Windows, parsing of templates is delayed until instantiation time.
        # This makes GetType and GetParent commands fail to return the expected
        # result when the cursor is in a template.
        # Using the -fno-delayed-template-parsing flag disables this behavior. See
        # http://clang.llvm.org/extra/PassByValueTransform.html#note-about-delayed-template-parsing # noqa
        # for an explanation of the flag and
        # https://code.google.com/p/include-what-you-use/source/detail?r=566
        # for a similar issue.
        if OnWindows():
            flags.append('-fno-delayed-template-parsing')
        if OnMac():
            flags = _AddMacIncludePaths(flags)
        flags = _EnableTypoCorrection(flags)

    vector = ycm_core.StringVector()
    for flag in flags:
        vector.append(ToCppStringCompatible(flag))
    return vector
Esempio n. 11
0
    def AddIdentifier(self, identifier, request_data):
        try:
            filetype = request_data['filetypes'][0]
        except KeyError:
            filetype = None
        filepath = request_data['filepath']

        if not filetype or not filepath or not identifier:
            return

        vector = ycm_core.StringVector()
        vector.append(ToCppStringCompatible(identifier))
        self._logger.info('Adding ONE buffer identifier for file: %s',
                          filepath)
        self._completer.AddIdentifiersToDatabase(
            vector, ToCppStringCompatible(filetype),
            ToCppStringCompatible(filepath))
def _IdentifiersFromBuffer(text, filetype, collect_from_comments_and_strings):
    if not collect_from_comments_and_strings:
        text = identifier_utils.RemoveIdentifierFreeText(text)
    idents = identifier_utils.ExtractIdentifiersFromText(text, filetype)
    vector = ycm_core.StringVector()
    for ident in idents:
        vector.append(ToCppStringCompatible(ident))
    return vector
Esempio n. 13
0
  def GetUnsavedFilesVector( self, request_data ):
    files = ycm_core.UnsavedFileVector()
    for filename, file_data in iteritems( request_data[ 'file_data' ] ):
      if not ClangAvailableForFiletypes( file_data[ 'filetypes' ] ):
        continue
      contents = file_data[ 'contents' ]
      if not contents or not filename:
        continue

      unsaved_file = ycm_core.UnsavedFile()
      utf8_contents = ToCppStringCompatible( contents )
      unsaved_file.contents_ = utf8_contents
      unsaved_file.length_ = len( utf8_contents )
      unsaved_file.filename_ = ToCppStringCompatible( filename )

      files.append( unsaved_file )
    return files
    def ComputeCandidates(self, request_data):
        if not self.ShouldUseNow(request_data):
            return []

        completions = self._completer.CandidatesForQueryAndType(
            ToCppStringCompatible(_SanitizeQuery(request_data['query'])),
            ToCppStringCompatible(request_data['first_filetype']))

        completions = completions[:self._max_candidates]
        completions = _RemoveSmallCandidates(
            completions,
            self.user_options['min_num_identifier_candidate_chars'])

        def ConvertCompletionData(x):
            return responses.BuildCompletionData(insertion_text=x,
                                                 extra_menu_info='[ID]')

        return [ConvertCompletionData(x) for x in completions]
    def _AddIdentifiersFromTagFiles(self, tag_files):
        absolute_paths_to_tag_files = ycm_core.StringVector()
        for tag_file in self._FilterUnchangedTagFiles(tag_files):
            absolute_paths_to_tag_files.append(ToCppStringCompatible(tag_file))

        if not absolute_paths_to_tag_files:
            return

        self._completer.AddIdentifiersToDatabaseFromTagFiles(
            absolute_paths_to_tag_files)
Esempio n. 16
0
File: flags.py Progetto: niuys/ycmd
def PrepareFlagsForClang(flags, filename, add_extra_clang_flags=True):
    flags = _AddLanguageFlagWhenAppropriate(flags)
    flags = _RemoveXclangFlags(flags)
    flags = _RemoveUnusedFlags(flags, filename)
    if add_extra_clang_flags:
        flags = _EnableTypoCorrection(flags)

    vector = ycm_core.StringVector()
    for flag in flags:
        vector.append(ToCppStringCompatible(flag))
    return vector
Esempio n. 17
0
 def OnBufferUnload(self, request_data):
     # FIXME: The filepath here is (possibly) wrong when overriding the
     # translation unit filename. If the buffer that the user closed is not the
     # "translation unit" filename, then we won't close the unit. It would
     # require the user to open the translation unit file, and close that.
     # Incidentally, doing so would flush the unit for any _other_ open files
     # which use that translation unit.
     #
     # Solving this would require remembering the graph of files to translation
     # units and only closing a unit when there are no files open which use it.
     self._completer.DeleteCachesForFile(
         ToCppStringCompatible(request_data['filepath']))
Esempio n. 18
0
def PrepareFlagsForClang(flags, filename, add_extra_clang_flags=True):
    flags = _AddLanguageFlagWhenAppropriate(flags)
    flags = _RemoveXclangFlags(flags)
    flags = _RemoveUnusedFlags(flags, filename)
    if add_extra_clang_flags:
        if OnMac() and not _SysRootSpecifedIn(flags):
            for path in _MacIncludePaths():
                flags.extend(['-isystem', path])
        flags = _EnableTypoCorrection(flags)

    vector = ycm_core.StringVector()
    for flag in flags:
        vector.append(ToCppStringCompatible(flag))
    return vector
Esempio n. 19
0
    def OnFileReadyToParse(self, request_data):
        flags, filename = self._FlagsForRequest(request_data)
        if not flags:
            raise ValueError(NO_COMPILE_FLAGS_MESSAGE)

        with self._files_being_compiled.GetExclusive(filename):
            diagnostics = self._completer.UpdateTranslationUnit(
                ToCppStringCompatible(filename),
                self.GetUnsavedFilesVector(request_data), flags)

        diagnostics = _FilterDiagnostics(diagnostics)
        self._diagnostic_store = DiagnosticsToDiagStructure(diagnostics)
        return responses.BuildDiagnosticResponse(
            diagnostics, request_data['filepath'],
            self.max_diagnostics_to_display)
Esempio n. 20
0
def FilterAndSortCandidatesWrap(candidates, sort_property, query):
    from ycm_core import FilterAndSortCandidates

    # The c++ interface we use only understands the (*native*) 'str' type (i.e.
    # not the 'str' type from python-future. If we pass it a 'unicode' or
    # 'bytes' instance then various things blow up, such as converting to
    # std::string. Therefore all strings passed into the c++ API must pass through
    # ToCppStringCompatible (or more strictly all strings which the C++ code
    # needs to use and convert. In this case, just the insertion text property)

    # FIXME: This is actually quite inefficient in an area which is used
    # constantly and the key performance critical part of the system. There is
    # code in the C++ layer (see PythonSupport.cpp:GetUtf8String) which attempts
    # to work around this limitation. Unfortunately it has issues which cause the
    # above problems, and we work around it by converting here in the python
    # layer until we can come up with a better solution in the C++ layer.

    # Note: we must deep copy candidates because we do not want to clobber the
    # data that is passed in. It is actually used directly by the cache, so if
    # we change the data pointed to by the elements of candidates, then this will
    # be reflected in a subsequent response from the cache. This is particularly
    # important for those candidates which are *not* returned after the filter, as
    # they are not converted back to unicode.
    cpp_compatible_candidates = _ConvertCandidatesToCppCompatible(
        copy.deepcopy(candidates), sort_property)

    # However, the reset of the python layer expects all the candidates properties
    # to be some form of unicode string - a python-future str() instance.
    # So we need to convert the insertion text property back to a unicode string
    # before returning it.
    filtered_candidates = FilterAndSortCandidates(
        cpp_compatible_candidates, ToCppStringCompatible(sort_property),
        ToCppStringCompatible(query))

    return _ConvertCandidatesToPythonCompatible(filtered_candidates,
                                                sort_property)
Esempio n. 21
0
def _SanitizeFlags(flags):
    """Drops unsafe flags. Currently these are only -arch flags; they tend to
  crash libclang."""

    sanitized_flags = []
    saw_arch = False
    for i, flag in enumerate(flags):
        if flag == '-arch':
            saw_arch = True
            continue
        elif flag.startswith('-arch'):
            continue
        elif saw_arch:
            saw_arch = False
            continue

        sanitized_flags.append(flag)

    vector = ycm_core.StringVector()
    for flag in sanitized_flags:
        vector.append(ToCppStringCompatible(flag))
    return vector
Esempio n. 22
0
    def AddIdentifiersFromTagFiles(self, tag_files):
        absolute_paths_to_tag_files = ycm_core.StringVector()
        for tag_file in tag_files:
            try:
                current_mtime = os.path.getmtime(tag_file)
            except:
                continue
            last_mtime = self._tags_file_last_mtime[tag_file]

            # We don't want to repeatedly process the same file over and over; we only
            # process if it's changed since the last time we looked at it
            if current_mtime <= last_mtime:
                continue

            self._tags_file_last_mtime[tag_file] = current_mtime
            absolute_paths_to_tag_files.append(ToCppStringCompatible(tag_file))

        if not absolute_paths_to_tag_files:
            return

        self._completer.AddIdentifiersToDatabaseFromTagFiles(
            absolute_paths_to_tag_files)
Esempio n. 23
0
def SetResponseHeader(name, value):
    name = ToCppStringCompatible(name) if PY2 else ToUnicode(name)
    value = ToCppStringCompatible(value) if PY2 else ToUnicode(value)
    bottle.response.set_header(name, value)
Esempio n. 24
0
 def OnBufferUnload( self, request_data ):
   self._completer.DeleteCachesForFile(
       ToCppStringCompatible( request_data[ 'filepath' ] ) )
    def ComputeCandidates(self, request_data):
        if not self.ShouldUseNow(request_data):
            return []

        completions = self._completer.CandidatesForQueryAndType(
            ToCppStringCompatible(_SanitizeQuery(request_data['query'])),
            ToCppStringCompatible(request_data['first_filetype']),
            self._max_candidates)

        completions = _RemoveSmallCandidates(
            completions,
            self.user_options['min_num_identifier_candidate_chars'])

        def ConvertCompletionData(x):
            return responses.BuildCompletionData(insertion_text=x,
                                                 extra_menu_info='[ID]')

        # ==== Manual hack for customized autocomplete ====
        #  return [ ConvertCompletionData( x ) for x in completions ]

        # -- for DEBUG --
        #  from collections import defaultdict
        #  mytest = [responses.BuildCompletionData(
        #    insertion_text = str(v[0]()),
        #    extra_menu_info = str(k), # '[SHORTCUT]',
        #    detailed_info = 'pdb shortcut',
        #    kind = None,
        #    extra_data = defaultdict(lambda x: 'completion_extra_data_placeholder'),
        #  ) for k, v in request_data._computed_key.items()]
        # -- DEBUG end --

        # This part adds customized autocompletion for non-triggered
        # identifiers. For triggered identifiers (e.g. completion after
        # dot in python), customization should be added to the filetype-
        # specific completer.
        from collections import defaultdict
        insertion_text = None
        query = request_data['query']
        if 'python' in request_data['filetypes']:
            if query == 'pdb':
                additional_identifier = insertion_text = 'import pdb; pdb.set_trace(); _ = 1'
            elif request_data['prefix'].endswith('import '):
                insertion_text = {
                    'np': 'numpy as np',
                    'numpy': 'numpy as np',
                    'pd': 'pandas as pd',
                    'pandas': 'pandas as pd',
                    'plt': 'matplotlib.pyplot as plt',
                    'pdb': 'pdb; pdb.set_trace(); _ = 1',
                }.get(query, None)
        if insertion_text:
            additional_identifier = [
                responses.BuildCompletionData(
                    insertion_text=insertion_text,
                    extra_menu_info='[SHORTCUT]',
                    detailed_info='oneliner shortcut',
                    extra_data=defaultdict(
                        lambda x: 'completion_extra_data_placeholder'))
            ]
        else:
            additional_identifier = []
        converted_completions = [ConvertCompletionData(x) for x in completions]
        return converted_completions[:
                                     1] + additional_identifier + converted_completions[
                                         1:]
Esempio n. 26
0
def FilterAndSortCandidatesShim( candidates, sort_property, query ):
  return FilterAndSortCandidates( candidates,
                                  ToCppStringCompatible( sort_property ),
                                  ToCppStringCompatible( query ) )
Esempio n. 27
0
def FilterAndSortCandidatesWrap(candidates, sort_property, query):
    from ycm_core import FilterAndSortCandidates
    return FilterAndSortCandidates(candidates,
                                   ToCppStringCompatible(sort_property),
                                   ToCppStringCompatible(query))