Example #1
0
def GetReady():
  LOGGER.info( 'Received ready request' )
  if request.query.subserver:
    filetype = request.query.subserver
    completer = _server_state.GetFiletypeCompleter( [ filetype ] )
    return _JsonResponse( completer.ServerIsReady() )
  return _JsonResponse( True )
Example #2
0
 def _ChooseOmnisharpPort( self ):
   if not self._omnisharp_port:
     if self._desired_omnisharp_port:
       self._omnisharp_port = int( self._desired_omnisharp_port )
     else:
       self._omnisharp_port = utils.GetUnusedLocalhostPort()
   LOGGER.info( 'using port %s', self._omnisharp_port )
  def StartServer( self, request_data ):
    with self._server_state_mutex:
      LOGGER.info( 'Starting %s: %s',
                   self.GetServerName(),
                   self.GetCommandLine() )

      self._stderr_file = utils.CreateLogfile( '{}_stderr'.format(
        utils.MakeSafeFileNameString( self.GetServerName() ) ) )

      with utils.OpenForStdHandle( self._stderr_file ) as stderr:
        self._server_handle = utils.SafePopen( self.GetCommandLine(),
                                               stdin = subprocess.PIPE,
                                               stdout = subprocess.PIPE,
                                               stderr = stderr )

      self._connection = (
        lsc.StandardIOLanguageServerConnection(
          self._server_handle.stdin,
          self._server_handle.stdout,
          self.GetDefaultNotificationHandler() )
      )

      self._connection.Start()

      try:
        self._connection.AwaitServerConnection()
      except lsc.LanguageServerConnectionTimeout:
        LOGGER.error( '%s failed to start, or did not connect successfully',
                      self.GetServerName() )
        self.Shutdown()
        return False

    LOGGER.info( '%s started', self.GetServerName() )

    return True
Example #4
0
    def __init__(self, user_options):
        self.user_options = user_options
        self.min_num_chars = user_options['min_num_of_chars_for_completion']
        self.max_diagnostics_to_display = user_options[
            'max_diagnostics_to_display']
        self.completion_triggers = (completer_utils.PreparedTriggers(
            user_trigger_map=user_options['semantic_triggers'],
            filetype_set=set(self.SupportedFiletypes()))
                                    if user_options['auto_trigger'] else None)

        self._signature_triggers = (
            completer_utils.PreparedTriggers(
                user_trigger_map=
                {},  # user triggers not supported for signature help
                filetype_set=set(self.SupportedFiletypes()),
                default_triggers={})
            if not user_options['disable_signature_help'] else None)

        self._completions_cache = CompletionsCache()
        self._max_candidates = user_options['max_num_candidates']
        self._max_candidates_to_detail = user_options[
            'max_num_candidates_to_detail']

        LOGGER.info(f"Completion config: { self._max_candidates }, detailing "
                    f"{ self._max_candidates_to_detail } candiates")
Example #5
0
def ShouldEnableCsCompleter(user_options):
    roslyn = FindExecutableWithFallback(user_options['roslyn_binary_path'],
                                        PATH_TO_OMNISHARP_ROSLYN_BINARY)
    if roslyn:
        return True
    LOGGER.info('No omnisharp-roslyn executable at %s', roslyn)
    return False
Example #6
0
    def StartServer(self, request_data):
        with self._server_state_mutex:
            if self.ServerIsHealthy():
                return

            # Ensure we cleanup all states.
            self._Reset()

            LOGGER.info('Starting clangd: %s', self._clangd_command)
            self._stderr_file = utils.CreateLogfile('clangd_stderr')
            with utils.OpenForStdHandle(self._stderr_file) as stderr:
                self._server_handle = utils.SafePopen(self._clangd_command,
                                                      stdin=subprocess.PIPE,
                                                      stdout=subprocess.PIPE,
                                                      stderr=stderr)

            self._connection = (
                language_server_completer.StandardIOLanguageServerConnection(
                    self._server_handle.stdin, self._server_handle.stdout,
                    self.GetDefaultNotificationHandler()))

            self._connection.Start()

            try:
                self._connection.AwaitServerConnection()
            except language_server_completer.LanguageServerConnectionTimeout:
                LOGGER.error('clangd failed to start, or did not connect '
                             'successfully')
                self.Shutdown()
                return

        LOGGER.info('clangd started')

        self.SendInitialize(request_data)
Example #7
0
def _CallGlobalExtraConfMethod( function_name ):
  global_ycm_extra_conf = _GlobalYcmExtraConfFileLocation()
  if not ( global_ycm_extra_conf and
           os.path.exists( global_ycm_extra_conf ) ):
    LOGGER.debug( 'No global extra conf, not calling method %s', function_name )
    return

  try:
    module = Load( global_ycm_extra_conf, force = True )
  except Exception:
    LOGGER.exception( 'Error occurred while loading global extra conf %s',
                      global_ycm_extra_conf )
    return

  if not module or not hasattr( module, function_name ):
    LOGGER.debug( 'Global extra conf not loaded or no function %s',
                  function_name )
    return

  try:
    LOGGER.info( 'Calling global extra conf method %s on conf file %s',
                 function_name,
                 global_ycm_extra_conf )
    getattr( module, function_name )()
  except Exception:
    LOGGER.exception(
      'Error occurred while calling global extra conf method %s '
      'on conf file %s', function_name, global_ycm_extra_conf )
Example #8
0
def PollModule(module, filepath):
    """ Try to use passed module in the selection process by calling
  CSharpSolutionFile on it """
    path_to_solutionfile = None
    module_hint = None
    if module:
        try:
            module_hint = module.CSharpSolutionFile(filepath)
            LOGGER.info('extra_conf_store suggests %s as solution file',
                        module_hint)
            if module_hint:
                # received a full path or one relative to the config's location?
                candidates = [
                    module_hint,
                    os.path.join(os.path.dirname(getfile(module)), module_hint)
                ]
                # try the assumptions
                for path in candidates:
                    if os.path.isfile(path):
                        # path seems to point to a solution
                        path_to_solutionfile = path
                        LOGGER.info(
                            'Using solution file %s selected by extra_conf_store',
                            path_to_solutionfile)
                        break
        except AttributeError:
            # the config script might not provide solution file locations
            LOGGER.exception(
                'Could not retrieve solution for %s'
                'from extra_conf_store', filepath)
    return path_to_solutionfile
Example #9
0
def GetClangdExecutableAndResourceDir(user_options):
    """Return the Clangd binary from the path specified in the
  'clangd_binary_path' option. Let the binary find its resource directory in
  that case. If no binary is found or if it's out-of-date, return nothing. If
  'clangd_binary_path' is empty, return the third-party Clangd and its resource
  directory if the user downloaded it and if it's up to date. Otherwise, return
  nothing."""
    clangd = user_options['clangd_binary_path']
    resource_dir = None

    if clangd:
        clangd = FindExecutable(ExpandVariablesInPath(clangd))

        if not clangd:
            LOGGER.error('No Clangd executable found at %s',
                         user_options['clangd_binary_path'])
            return None, None

        if not CheckClangdVersion(clangd):
            LOGGER.error('Clangd at %s is out-of-date', clangd)
            return None, None

    # Try looking for the pre-built binary.
    else:
        third_party_clangd = GetThirdPartyClangd()
        if not third_party_clangd:
            return None, None
        clangd = third_party_clangd
        resource_dir = CLANG_RESOURCE_DIR

    LOGGER.info('Using Clangd from %s', clangd)
    return clangd, resource_dir
Example #10
0
    def _StartServerNoLock(self):
        if self._ServerIsRunning():
            return

        self._logfile = utils.CreateLogfile(LOGFILE_FORMAT)
        tsserver_log = f'-file { self._logfile } -level {_LogLevel()}'
        # TSServer gets the configuration for the log file through the
        # environment variable 'TSS_LOG'. This seems to be undocumented but
        # looking at the source code it seems like this is the way:
        # https://github.com/Microsoft/TypeScript/blob/8a93b489454fdcbdf544edef05f73a913449be1d/src/server/server.ts#L136
        environ = os.environ.copy()
        environ['TSS_LOG'] = tsserver_log

        # TSServer runs out of memory on larger projects. This is the value that
        # VSCode uses.
        environ['NODE_OPTIONS'] = '--max_old_space_size=3072'

        LOGGER.info('TSServer log file: %s', self._logfile)

        # We need to redirect the error stream to the output one on Windows.
        self._tsserver_handle = utils.SafePopen(self._tsserver_executable,
                                                stdin=subprocess.PIPE,
                                                stdout=subprocess.PIPE,
                                                stderr=subprocess.STDOUT,
                                                env=environ)

        LOGGER.info("TSServer started with PID %s", self._tsserver_handle.pid)
        self._tsserver_is_running.set()

        utils.StartThread(self._SetServerVersion)
def GetClangdCommand(user_options):
    global CLANGD_COMMAND
    # None stands for we tried to fetch command and failed, therefore it is not
    # the default.
    if CLANGD_COMMAND != NOT_CACHED:
        LOGGER.info('Returning cached Clangd command: %s', CLANGD_COMMAND)
        return CLANGD_COMMAND
    CLANGD_COMMAND = None

    installed_clangd, resource_dir = GetClangdExecutableAndResourceDir(
        user_options)
    if not installed_clangd:
        return None

    CLANGD_COMMAND = [installed_clangd]
    clangd_args = user_options['clangd_args']
    put_resource_dir = False
    put_limit_results = False
    put_header_insertion_decorators = False
    for arg in clangd_args:
        CLANGD_COMMAND.append(arg)
        put_resource_dir = put_resource_dir or arg.startswith('-resource-dir')
        put_limit_results = put_limit_results or arg.startswith(
            '-limit-results')
        put_header_insertion_decorators = (
            put_header_insertion_decorators
            or arg.startswith('-header-insertion-decorators'))
    if not put_header_insertion_decorators:
        CLANGD_COMMAND.append('-header-insertion-decorators=0')
    if resource_dir and not put_resource_dir:
        CLANGD_COMMAND.append('-resource-dir=' + resource_dir)
    if user_options['clangd_uses_ycmd_caching'] and not put_limit_results:
        CLANGD_COMMAND.append('-limit-results=500')

    return CLANGD_COMMAND
  def _ReaderLoop( self ):
    """
    Read responses from TSServer and use them to resolve
    the DeferredResponse instances.
    """

    while True:
      self._tsserver_is_running.wait()

      try:
        message = self._ReadMessage()
      except ( RuntimeError, ValueError ):
        LOGGER.exception( 'Error while reading message from server' )
        if not self._ServerIsRunning():
          self._tsserver_is_running.clear()
        continue

      # We ignore events for now since we don't have a use for them.
      msgtype = message[ 'type' ]
      if msgtype == 'event':
        eventname = message[ 'event' ]
        LOGGER.info( 'Received %s event from TSServer',  eventname )
        continue
      if msgtype != 'response':
        LOGGER.error( 'Unsupported message type', msgtype )
        continue

      seq = message[ 'request_seq' ]
      with self._pending_lock:
        if seq in self._pending:
          self._pending[ seq ].resolve( message )
          del self._pending[ seq ]
Example #13
0
    def _StartServer(self):
        """Start the Gocode server."""
        with self._gocode_lock:
            LOGGER.info('Starting Gocode server')

            self._gocode_port = utils.GetUnusedLocalhostPort()
            self._gocode_host = '127.0.0.1:{0}'.format(self._gocode_port)

            command = [
                self._gocode_binary_path, '-s', '-sock', 'tcp', '-addr',
                self._gocode_host
            ]

            if LOGGER.isEnabledFor(logging.DEBUG):
                command.append('-debug')

            self._gocode_stdout = utils.CreateLogfile(
                LOGFILE_FORMAT.format(port=self._gocode_port, std='stdout'))
            self._gocode_stderr = utils.CreateLogfile(
                LOGFILE_FORMAT.format(port=self._gocode_port, std='stderr'))

            with utils.OpenForStdHandle(self._gocode_stdout) as stdout:
                with utils.OpenForStdHandle(self._gocode_stderr) as stderr:
                    self._gocode_handle = utils.SafePopen(command,
                                                          stdout=stdout,
                                                          stderr=stderr)
Example #14
0
    def StartServer(self, request_data):
        with self._server_state_mutex:
            LOGGER.info('Starting %s: %s', self.GetServerName(),
                        self.GetCommandLine())

            self._stderr_file = utils.CreateLogfile('{}_stderr'.format(
                utils.MakeSafeFileNameString(self.GetServerName())))

            with utils.OpenForStdHandle(self._stderr_file) as stderr:
                self._server_handle = utils.SafePopen(self.GetCommandLine(),
                                                      stdin=subprocess.PIPE,
                                                      stdout=subprocess.PIPE,
                                                      stderr=stderr)

            self._connection = (lsc.StandardIOLanguageServerConnection(
                self._server_handle.stdin, self._server_handle.stdout,
                self.GetDefaultNotificationHandler()))

            self._connection.Start()

            try:
                self._connection.AwaitServerConnection()
            except lsc.LanguageServerConnectionTimeout:
                LOGGER.error(
                    '%s failed to start, or did not connect successfully',
                    self.GetServerName())
                self.Shutdown()
                return False

        LOGGER.info('%s started', self.GetServerName())

        return True
  def _StartServer( self ):
    with self._tsserver_lock:
      if self._ServerIsRunning():
        return

      self._logfile = utils.CreateLogfile( LOGFILE_FORMAT )
      tsserver_log = '-file {path} -level {level}'.format( path = self._logfile,
                                                           level = _LogLevel() )
      # TSServer gets the configuration for the log file through the
      # environment variable 'TSS_LOG'. This seems to be undocumented but
      # looking at the source code it seems like this is the way:
      # https://github.com/Microsoft/TypeScript/blob/8a93b489454fdcbdf544edef05f73a913449be1d/src/server/server.ts#L136
      environ = os.environ.copy()
      utils.SetEnviron( environ, 'TSS_LOG', tsserver_log )

      LOGGER.info( 'TSServer log file: %s', self._logfile )

      # We need to redirect the error stream to the output one on Windows.
      self._tsserver_handle = utils.SafePopen( self._tsserver_executable,
                                               stdin = subprocess.PIPE,
                                               stdout = subprocess.PIPE,
                                               stderr = subprocess.STDOUT,
                                               env = environ )

      self._tsserver_is_running.set()

      utils.StartThread( self._SetServerVersion )
Example #16
0
def PollModule( module, filepath ):
  """ Try to use passed module in the selection process by calling
  CSharpSolutionFile on it """
  path_to_solutionfile = None
  module_hint = None
  if module:
    try:
      module_hint = module.CSharpSolutionFile( filepath )
      LOGGER.info( 'extra_conf_store suggests %s as solution file',
                   module_hint )
      if module_hint:
        # received a full path or one relative to the config's location?
        candidates = [ module_hint,
          os.path.join( os.path.dirname( getfile( module ) ),
                        module_hint ) ]
        # try the assumptions
        for path in candidates:
          if os.path.isfile( path ):
            # path seems to point to a solution
            path_to_solutionfile = path
            LOGGER.info( 'Using solution file %s selected by extra_conf_store',
                         path_to_solutionfile )
            break
    except AttributeError:
      # the config script might not provide solution file locations
      LOGGER.exception( 'Could not retrieve solution for %s'
                        'from extra_conf_store', filepath )
  return path_to_solutionfile
Example #17
0
    def _ReaderLoop(self):
        """
    Read responses from TSServer and use them to resolve
    the DeferredResponse instances.
    """

        while True:
            self._tsserver_is_running.wait()

            try:
                message = self._ReadMessage()
            except (RuntimeError, ValueError):
                LOGGER.exception('Error while reading message from server')
                if not self._ServerIsRunning():
                    self._tsserver_is_running.clear()
                continue

            # We ignore events for now since we don't have a use for them.
            msgtype = message['type']
            if msgtype == 'event':
                eventname = message['event']
                LOGGER.info('Received %s event from TSServer', eventname)
                continue
            if msgtype != 'response':
                LOGGER.error('Unsupported message type', msgtype)
                continue

            seq = message['request_seq']
            with self._pending_lock:
                if seq in self._pending:
                    self._pending[seq].resolve(message)
                    del self._pending[seq]
Example #18
0
def GetSemanticTokens():
    LOGGER.info('Received semantic tokens request')
    request_data = RequestWrap(request.json)

    if not _server_state.FiletypeCompletionUsable(request_data['filetypes'],
                                                  silent=True):
        return _JsonResponse(BuildSemanticTokensResponse(None))

    errors = None
    semantic_tokens = None

    try:
        filetype_completer = _server_state.GetFiletypeCompleter(
            request_data['filetypes'])
        semantic_tokens = filetype_completer.ComputeSemanticTokens(
            request_data)
    except Exception as exception:
        LOGGER.exception(
            'Exception from semantic completer during tokens request')
        errors = [BuildExceptionResponse(exception, traceback.format_exc())]

    # No fallback for signature help. The general completer is unlikely to be able
    # to offer anything of for that here.
    return _JsonResponse(
        BuildSemanticTokensResponse(semantic_tokens, errors=errors))
Example #19
0
    def _StartServer(self):
        with self._tsserver_lock:
            if self._ServerIsRunning():
                return

            self._logfile = utils.CreateLogfile(LOGFILE_FORMAT)
            tsserver_log = '-file {path} -level {level}'.format(
                path=self._logfile, level=_LogLevel())
            # TSServer gets the configuration for the log file through the
            # environment variable 'TSS_LOG'. This seems to be undocumented but
            # looking at the source code it seems like this is the way:
            # https://github.com/Microsoft/TypeScript/blob/8a93b489454fdcbdf544edef05f73a913449be1d/src/server/server.ts#L136
            environ = os.environ.copy()
            environ['TSS_LOG'] = tsserver_log

            LOGGER.info('TSServer log file: %s', self._logfile)

            # We need to redirect the error stream to the output one on Windows.
            self._tsserver_handle = utils.SafePopen(self._tsserver_executable,
                                                    stdin=subprocess.PIPE,
                                                    stdout=subprocess.PIPE,
                                                    stderr=subprocess.STDOUT,
                                                    env=environ)

            self._tsserver_is_running.set()

            utils.StartThread(self._SetServerVersion)
Example #20
0
def ShouldEnableRustCompleter():
    if not RLS_EXECUTABLE:
        LOGGER.error('Not using Rust completer: no RLS executable found at %s',
                     RLS_EXECUTABLE)
        return False
    LOGGER.info('Using Rust completer')
    return True
def _CallGlobalExtraConfMethod(function_name):
    global_ycm_extra_conf = _GlobalYcmExtraConfFileLocation()
    if not (global_ycm_extra_conf and os.path.exists(global_ycm_extra_conf)):
        LOGGER.debug('No global extra conf, not calling method %s',
                     function_name)
        return

    try:
        module = Load(global_ycm_extra_conf, force=True)
    except Exception:
        LOGGER.exception('Error occurred while loading global extra conf %s',
                         global_ycm_extra_conf)
        return

    if not module or not hasattr(module, function_name):
        LOGGER.debug('Global extra conf not loaded or no function %s',
                     function_name)
        return

    try:
        LOGGER.info('Calling global extra conf method %s on conf file %s',
                    function_name, global_ycm_extra_conf)
        getattr(module, function_name)()
    except Exception:
        LOGGER.exception(
            'Error occurred while calling global extra conf method %s '
            'on conf file %s', function_name, global_ycm_extra_conf)
Example #22
0
def GetClangdExecutableAndResourceDir( user_options ):
  """Return the Clangd binary from the path specified in the
  'clangd_binary_path' option. Let the binary find its resource directory in
  that case. If no binary is found or if it's out-of-date, return nothing. If
  'clangd_binary_path' is empty, return the third-party Clangd and its resource
  directory if the user downloaded it and if it's up to date. Otherwise, return
  nothing."""
  clangd = user_options[ 'clangd_binary_path' ]
  resource_dir = None

  if clangd:
    clangd = FindExecutable( ExpandVariablesInPath( clangd ) )

    if not clangd:
      LOGGER.error( 'No Clangd executable found at %s',
                    user_options[ 'clangd_binary_path' ] )
      return None, None

    if not CheckClangdVersion( clangd ):
      LOGGER.error( 'Clangd at %s is out-of-date', clangd )
      return None, None

  # Try looking for the pre-built binary.
  else:
    third_party_clangd = GetThirdPartyClangd()
    if not third_party_clangd:
      return None, None
    clangd = third_party_clangd
    resource_dir = CLANG_RESOURCE_DIR

  LOGGER.info( 'Using Clangd from %s', clangd )
  return clangd, resource_dir
Example #23
0
def GetReady():
    LOGGER.info('Received ready request')
    if request.query.subserver:
        filetype = request.query.subserver
        completer = _server_state.GetFiletypeCompleter([filetype])
        return _JsonResponse(completer.ServerIsReady())
    return _JsonResponse(True)
Example #24
0
def RunCompleterCommand():
  LOGGER.info( 'Received command request' )
  request_data = RequestWrap( request.json )
  completer = _GetCompleterForRequestData( request_data )

  return _JsonResponse( completer.OnUserCommand(
      request_data[ 'command_arguments' ],
      request_data ) )
Example #25
0
def RunCompleterCommand():
    LOGGER.info('Received command request')
    request_data = RequestWrap(request.json)
    completer = _GetCompleterForRequestData(request_data)

    return _JsonResponse(
        completer.OnUserCommand(request_data['command_arguments'],
                                request_data))
def ShouldEnableTypeScriptCompleter():
  tsserver = FindTSServer()
  if not tsserver:
    LOGGER.error( 'Not using TypeScript completer: TSServer not installed '
                  'in %s', TSSERVER_DIR )
    return False
  LOGGER.info( 'Using TypeScript completer with %s', tsserver )
  return True
Example #27
0
def ShouldEnableTypeScriptCompleter( user_options ):
  tsserver = FindTSServer( user_options[ 'tsserver_binary_path' ] )
  if not tsserver:
    LOGGER.error( 'Not using TypeScript completer: TSServer not installed '
                  'in %s', TSSERVER_DIR )
    return False
  LOGGER.info( 'Using TypeScript completer with %s', tsserver )
  return True
Example #28
0
    def StartServer(self, request_data, project_directory=None):
        with self._server_state_mutex:
            LOGGER.info('Starting jdt.ls Language Server...')

            if project_directory:
                self._java_project_dir = project_directory
            else:
                self._java_project_dir = _FindProjectDir(
                    os.path.dirname(request_data['filepath']))

            self._workspace_path = _WorkspaceDirForProject(
                self._java_project_dir, self._use_clean_workspace)

            command = [
                PATH_TO_JAVA,
                '-Dfile.encoding=UTF-8',
                '-Declipse.application=org.eclipse.jdt.ls.core.id1',
                '-Dosgi.bundles.defaultStartLevel=4',
                '-Declipse.product=org.eclipse.jdt.ls.core.product',
                '-Dlog.level=ALL',
                '-jar',
                self._launcher_path,
                '-configuration',
                self._launcher_config,
                '-data',
                self._workspace_path,
            ]

            LOGGER.debug('Starting java-server with the following command: %s',
                         command)

            self._server_stderr = utils.CreateLogfile('jdt.ls_stderr_')
            with utils.OpenForStdHandle(self._server_stderr) as stderr:
                self._server_handle = utils.SafePopen(command,
                                                      stdin=PIPE,
                                                      stdout=PIPE,
                                                      stderr=stderr)

            self._connection = (
                language_server_completer.StandardIOLanguageServerConnection(
                    self._server_handle.stdin, self._server_handle.stdout,
                    self.GetDefaultNotificationHandler()))

            self._connection.Start()

            try:
                self._connection.AwaitServerConnection()
            except language_server_completer.LanguageServerConnectionTimeout:
                LOGGER.error('jdt.ls failed to start, or did not connect '
                             'successfully')
                self.Shutdown()
                return False

        LOGGER.info('jdt.ls Language Server started')

        return True
Example #29
0
  def StartServer( self, request_data, project_directory = None ):
    with self._server_state_mutex:
      LOGGER.info( 'Starting jdt.ls Language Server...' )

      if project_directory:
        self._java_project_dir = project_directory
      else:
        self._java_project_dir = _FindProjectDir(
          os.path.dirname( request_data[ 'filepath' ] ) )

      self._workspace_path = _WorkspaceDirForProject(
        self._java_project_dir,
        self._use_clean_workspace )

      command = [
        PATH_TO_JAVA,
        '-Dfile.encoding=UTF-8',
        '-Declipse.application=org.eclipse.jdt.ls.core.id1',
        '-Dosgi.bundles.defaultStartLevel=4',
        '-Declipse.product=org.eclipse.jdt.ls.core.product',
        '-Dlog.level=ALL',
        '-jar', self._launcher_path,
        '-configuration', self._launcher_config,
        '-data', self._workspace_path,
      ]

      LOGGER.debug( 'Starting java-server with the following command: %s',
                    command )

      self._server_stderr = utils.CreateLogfile( 'jdt.ls_stderr_' )
      with utils.OpenForStdHandle( self._server_stderr ) as stderr:
        self._server_handle = utils.SafePopen( command,
                                               stdin = PIPE,
                                               stdout = PIPE,
                                               stderr = stderr )

      self._connection = (
        language_server_completer.StandardIOLanguageServerConnection(
          self._server_handle.stdin,
          self._server_handle.stdout,
          self.GetDefaultNotificationHandler() )
      )

      self._connection.Start()

      try:
        self._connection.AwaitServerConnection()
      except language_server_completer.LanguageServerConnectionTimeout:
        LOGGER.error( 'jdt.ls failed to start, or did not connect '
                      'successfully' )
        self.Shutdown()
        return False

    LOGGER.info( 'jdt.ls Language Server started' )

    return True
    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

        LOGGER.info('Adding ONE buffer identifier for file: %s', filepath)
        self._completer.AddSingleIdentifierToDatabase(identifier, filetype,
                                                      filepath)
Example #31
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

        LOGGER.info('Adding ONE buffer identifier for file: %s', filepath)
        self._completer.AddIdentifiersToDatabase(
            ycm_core.StringVector([identifier]), filetype, filepath)
Example #32
0
    def StartServer(self,
                    request_data,
                    project_directory=None,
                    wipe_workspace=False,
                    wipe_config=False):
        try:
            with self._server_info_mutex:
                LOGGER.info('Starting jdt.ls Language Server...')

                if project_directory:
                    self._java_project_dir = project_directory
                elif 'project_directory' in self._settings:
                    self._java_project_dir = utils.AbsolutePath(
                        self._settings['project_directory'],
                        self._extra_conf_dir)
                else:
                    self._java_project_dir = _FindProjectDir(
                        os.path.dirname(request_data['filepath']))

                self._workspace_path = _WorkspaceDirForProject(
                    self._workspace_root_path, self._java_project_dir,
                    self._use_clean_workspace)

                if not self._use_clean_workspace and wipe_workspace:
                    if os.path.isdir(self._workspace_path):
                        LOGGER.info(
                            f'Wiping out workspace { self._workspace_path }')
                        shutil.rmtree(self._workspace_path)

                self._launcher_config = _LauncherConfiguration(
                    self._workspace_root_path, wipe_config)

                self._command = [
                    PATH_TO_JAVA
                ] + self._GetJvmArgs(request_data) + [
                    '-Dfile.encoding=UTF-8',
                    '-Declipse.application=org.eclipse.jdt.ls.core.id1',
                    '-Dosgi.bundles.defaultStartLevel=4',
                    '-Declipse.product=org.eclipse.jdt.ls.core.product',
                    '-Dlog.level=ALL',
                    '-jar',
                    self._launcher_path,
                    '-configuration',
                    self._launcher_config,
                    '-data',
                    self._workspace_path,
                ]

                return super(JavaCompleter,
                             self)._StartServerNoLock(request_data)
        except language_server_completer.LanguageServerConnectionTimeout:
            LOGGER.error('%s failed to start, or did not connect successfully',
                         self.GetServerName())
            self.Shutdown()
            return False
Example #33
0
def FilterAndSortCandidates():
    LOGGER.info('Received filter & sort request')
    # Not using RequestWrap because no need and the requests coming in aren't like
    # the usual requests we handle.
    request_data = request.json

    return _JsonResponse(
        FilterAndSortCandidatesWrap(
            request_data['candidates'], request_data['sort_property'],
            request_data['query'],
            _server_state.user_options['max_num_candidates']))
Example #34
0
def GetThirdPartyClangd():
  pre_built_clangd = GetExecutable( PRE_BUILT_CLANDG_PATH )
  if not pre_built_clangd:
    LOGGER.info( 'No Clangd executable found in %s', PRE_BUILT_CLANGD_DIR )
    return None
  if not CheckClangdVersion( pre_built_clangd ):
    LOGGER.error( 'Clangd executable at %s is out-of-date', pre_built_clangd )
    return None
  LOGGER.info( 'Clangd executable found at %s and up to date',
               PRE_BUILT_CLANGD_DIR )
  return pre_built_clangd
Example #35
0
def GetThirdPartyClangd():
  pre_built_clangd = GetExecutable( PRE_BUILT_CLANDG_PATH )
  if not pre_built_clangd:
    LOGGER.info( 'No Clangd executable found in %s', PRE_BUILT_CLANGD_DIR )
    return None
  if not CheckClangdVersion( pre_built_clangd ):
    LOGGER.error( 'Clangd executable at %s is out-of-date', pre_built_clangd )
    return None
  LOGGER.info( 'Clangd executable found at %s and up to date',
               PRE_BUILT_CLANGD_DIR )
  return pre_built_clangd
Example #36
0
def FilterAndSortCandidates():
  LOGGER.info( 'Received filter & sort request' )
  # Not using RequestWrap because no need and the requests coming in aren't like
  # the usual requests we handle.
  request_data = request.json

  return _JsonResponse( FilterAndSortCandidatesWrap(
    request_data[ 'candidates' ],
    request_data[ 'sort_property' ],
    request_data[ 'query' ],
    _server_state.user_options[ 'max_num_candidates' ] ) )
Example #37
0
  def HandleNotificationInPollThread( self, notification ):
    if notification[ 'method' ] == 'language/status':
      message_type = notification[ 'params' ][ 'type' ]

      if message_type == 'Started':
        LOGGER.info( 'jdt.ls initialized successfully' )
        self._received_ready_message.set()

      self._server_init_status = notification[ 'params' ][ 'message' ]

    super( JavaCompleter, self ).HandleNotificationInPollThread( notification )
Example #38
0
  def HandleNotificationInPollThread( self, notification ):
    if notification[ 'method' ] == 'language/status':
      message_type = notification[ 'params' ][ 'type' ]

      if message_type == 'Started':
        LOGGER.info( 'jdt.ls initialized successfully' )
        self._server_init_status = notification[ 'params' ][ 'message' ]
        self._received_ready_message.set()
      elif not self._received_ready_message.is_set():
        self._server_init_status = notification[ 'params' ][ 'message' ]

    super( JavaCompleter, self ).HandleNotificationInPollThread( notification )
Example #39
0
  def _StopServer( self ):
    with self._server_state_lock:
      if self._racerd_phandle:
        LOGGER.info( 'Stopping Racerd with PID %s', self._racerd_phandle.pid )
        self._racerd_phandle.terminate()
        try:
          utils.WaitUntilProcessIsTerminated( self._racerd_phandle,
                                              timeout = 5 )
          LOGGER.info( 'Racerd stopped' )
        except RuntimeError:
          LOGGER.exception( 'Error while stopping Racerd' )

      self._CleanUp()
Example #40
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))
Example #41
0
    def _StopServerNoLock(self):
        if self._ServerIsRunning():
            LOGGER.info('Stopping Tern server with PID %s',
                        self._server_handle.pid)
            self._server_handle.terminate()
            try:
                utils.WaitUntilProcessIsTerminated(self._server_handle,
                                                   timeout=5)
                LOGGER.info('Tern server stopped')
            except RuntimeError:
                LOGGER.exception('Error while stopping Tern server')

        self._CleanUp()
Example #42
0
def ResolveCompletionItem():
    LOGGER.info("Received resolve request")
    request_data = RequestWrap(request.json)
    completer = _GetCompleterForRequestData(request_data)

    errors = None
    completion = None
    try:
        completion = completer.ResolveCompletionItem(request_data)
    except Exception as e:
        errors = [BuildExceptionResponse(e, traceback.format_exc())]

    return _JsonResponse(BuildResolveCompletionResponse(completion, errors))
Example #43
0
  def _StopServerNoLock( self ):
    if self._ServerIsRunning():
      LOGGER.info( 'Stopping TSServer with PID %s',
                   self._tsserver_handle.pid )
      try:
        self._SendCommand( 'exit' )
        utils.WaitUntilProcessIsTerminated( self._tsserver_handle,
                                            timeout = 5 )
        LOGGER.info( 'TSServer stopped' )
      except Exception:
        LOGGER.exception( 'Error while stopping TSServer' )

    self._CleanUp()
Example #44
0
def ShouldEnableRustCompleter(user_options):
    if GetExecutable(user_options['rls_binary_path']):
        if GetExecutable(user_options['rustc_binary_path']):
            return True
        else:
            LOGGER.error(
                'rustc_binary_path not specified, rls_binary_path ignored')
    if not RLS_EXECUTABLE:
        LOGGER.error('Not using Rust completer: no RLS executable found at %s',
                     RLS_EXECUTABLE)
        return False
    LOGGER.info('Using Rust completer')
    return True
  def _StopServer( self ):
    with self._tsserver_lock:
      if self._ServerIsRunning():
        LOGGER.info( 'Stopping TSServer with PID %s',
                     self._tsserver_handle.pid )
        try:
          self._SendCommand( 'exit' )
          utils.WaitUntilProcessIsTerminated( self._tsserver_handle,
                                              timeout = 5 )
          LOGGER.info( 'TSServer stopped' )
        except Exception:
          LOGGER.exception( 'Error while stopping TSServer' )

      self._CleanUp()
Example #46
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 ) )
Example #47
0
  def _StopServer( self ):
    with self._server_state_mutex:
      if self._ServerIsRunning():
        LOGGER.info( 'Stopping Tern server with PID %s',
                     self._server_handle.pid )
        self._server_handle.terminate()
        try:
          utils.WaitUntilProcessIsTerminated( self._server_handle,
                                              timeout = 5 )
          LOGGER.info( 'Tern server stopped' )
        except RuntimeError:
          LOGGER.exception( 'Error while stopping Tern server' )

      self._CleanUp()
Example #48
0
  def _WatchdogMain( self ):
    while True:
      time.sleep( self._check_interval_seconds )

      # We make sure we don't terminate if we skipped a wakeup time. If we
      # skipped a check, that means the machine probably went to sleep and the
      # client might still actually be up. In such cases, we give it one more
      # wait interval to contact us before we die.
      if ( self._TimeSinceLastRequest() > self._idle_suicide_seconds and
           self._TimeSinceLastWakeup() < 2 * self._check_interval_seconds ):
        LOGGER.info( 'Shutting down server due to inactivity' )
        ServerShutdown()

      self._UpdateLastWakeupTime()
Example #49
0
def ShouldEnableClangdCompleter( user_options ):
  """Checks whether clangd should be enabled or not.

  - Returns True iff an up-to-date binary exists either in `clangd_binary_path`
    or in third party folder and `use_clangd` is not set to `0`.
  """
  # User disabled clangd explicitly.
  if not user_options[ 'use_clangd' ]:
    return False

  clangd_command = GetClangdCommand( user_options )
  if not clangd_command:
    return False
  LOGGER.info( 'Computed Clangd command: %s', clangd_command )
  return True
Example #50
0
 def _SetServerProjectFileAndWorkingDirectory( self, request_data ):
   filepath = request_data[ 'filepath' ]
   self._server_project_file, is_project = FindTernProjectFile( filepath )
   working_dir = request_data.get( 'working_dir',
                                   utils.GetCurrentDirectory() )
   if not self._server_project_file:
     LOGGER.warning( 'No .tern-project file detected: %s', filepath )
     self._server_working_dir = working_dir
   else:
     LOGGER.info( 'Detected Tern configuration file at: %s',
                  self._server_project_file )
     self._server_working_dir = (
       os.path.dirname( self._server_project_file ) if is_project else
       working_dir )
   LOGGER.info( 'Tern paths are relative to: %s', self._server_working_dir )
def ShouldEnableClangdCompleter( user_options ):
  third_party_clangd = Get3rdPartyClangd()
  # User disabled clangd explicitly.
  if user_options[ 'use_clangd' ].lower() == 'never':
    return False
  # User haven't downloaded clangd and use_clangd is in auto mode.
  if not third_party_clangd and user_options[ 'use_clangd' ].lower() == 'auto':
    return False

  clangd_command = GetClangdCommand( user_options, third_party_clangd )
  if not clangd_command:
    LOGGER.warning( 'Not using clangd: unable to find clangd binary' )
    return False
  LOGGER.info( 'Using clangd from %s', clangd_command )
  return True
Example #52
0
def ShouldEnableJavaCompleter():
  LOGGER.info( 'Looking for jdt.ls' )
  if not PATH_TO_JAVA:
    LOGGER.warning( "Not enabling java completion: Couldn't find java" )
    return False

  if not os.path.exists( LANGUAGE_SERVER_HOME ):
    LOGGER.warning( 'Not using java completion: jdt.ls is not installed' )
    return False

  if not _PathToLauncherJar():
    LOGGER.warning( 'Not using java completion: jdt.ls is not built' )
    return False

  return True
Example #53
0
  def _StopServer( self ):
    """ Stop the OmniSharp server using a lock. """
    with self._server_state_lock:
      if self._ServerIsRunning():
        LOGGER.info( 'Stopping OmniSharp server with PID %s',
                     self._omnisharp_phandle.pid )
        try:
          self._GetResponse( '/stopserver' )
          utils.WaitUntilProcessIsTerminated( self._omnisharp_phandle,
                                              timeout = 5 )
          LOGGER.info( 'OmniSharp server stopped' )
        except Exception:
          LOGGER.exception( 'Error while stopping OmniSharp server' )

      self._CleanUp()
Example #54
0
    def wrapper( *args, **kwargs ):
      if not HostHeaderCorrect( request ):
        LOGGER.info( 'Dropping request with bad Host header' )
        abort( requests.codes.unauthorized,
               'Unauthorized, received bad Host header.' )
        return

      body = ToBytes( request.body.read() )
      if not RequestAuthenticated( request.method, request.path, body,
                                   self._hmac_secret ):
        LOGGER.info( 'Dropping request with bad HMAC' )
        abort( requests.codes.unauthorized, 'Unauthorized, received bad HMAC.' )
        return
      body = callback( *args, **kwargs )
      SetHmacHeader( body, self._hmac_secret )
      return body
Example #55
0
  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' ]
    LOGGER.info( 'Adding buffer identifiers for file: %s', filepath )
    self._completer.ClearForFileAndAddIdentifiersToDatabase(
        _IdentifiersFromBuffer( text,
                                filetype,
                                collect_from_comments_and_strings ),
        ToCppStringCompatible( filetype ),
        ToCppStringCompatible( filepath ) )
def GetClangdCommand( user_options, third_party_clangd ):
  """Get commands to run clangd.

  Look through binaries reachable through PATH or pre-built ones.
  Return None if no binary exists or it is out of date. """
  global CLANGD_COMMAND
  # None stands for we tried to fetch command and failed, therefore it is not
  # the default.
  if CLANGD_COMMAND != NOT_CACHED:
    LOGGER.info( 'Returning cached clangd: %s', CLANGD_COMMAND )
    return CLANGD_COMMAND
  CLANGD_COMMAND = None

  resource_dir = None
  installed_clangd = user_options[ 'clangd_binary_path' ]
  if not CheckClangdVersion( installed_clangd ):
    if installed_clangd:
      LOGGER.warning( 'Clangd at %s is out-of-date, trying to use pre-built '
                      'version', installed_clangd )
    # Try looking for the pre-built binary.
    if not third_party_clangd:
      return None
    installed_clangd = third_party_clangd
    resource_dir = CLANG_RESOURCE_DIR

  # We have a clangd binary that is executable and up-to-date at this point.
  CLANGD_COMMAND = [ installed_clangd ]
  clangd_args = user_options[ 'clangd_args' ]
  put_resource_dir = False
  put_limit_results = False
  put_header_insertion_decorators = False
  for arg in clangd_args:
    CLANGD_COMMAND.append( arg )
    put_resource_dir = put_resource_dir or arg.startswith( '-resource-dir' )
    put_limit_results = put_limit_results or arg.startswith( '-limit-results' )
    put_header_insertion_decorators = ( put_header_insertion_decorators or
                        arg.startswith( '-header-insertion-decorators' ) )
  if not put_header_insertion_decorators:
    CLANGD_COMMAND.append( '-header-insertion-decorators=0' )
  if resource_dir and not put_resource_dir:
    CLANGD_COMMAND.append( '-resource-dir=' + resource_dir )
  if user_options[ 'clangd_uses_ycmd_caching' ] and not put_limit_results:
    CLANGD_COMMAND.append( '-limit-results=500' )

  return CLANGD_COMMAND
Example #57
0
def EventNotification():
  LOGGER.info( 'Received event notification' )
  request_data = RequestWrap( request.json )
  event_name = request_data[ 'event_name' ]
  LOGGER.debug( 'Event name: %s', event_name )

  event_handler = 'On' + event_name
  getattr( _server_state.GetGeneralCompleter(), event_handler )( request_data )

  filetypes = request_data[ 'filetypes' ]
  response_data = None
  if _server_state.FiletypeCompletionUsable( filetypes ):
    response_data = getattr( _server_state.GetFiletypeCompleter( filetypes ),
                             event_handler )( request_data )

  if response_data:
    return _JsonResponse( response_data )
  return _JsonResponse( {} )
Example #58
0
  def _StartServer( self ):
    """ Start the OmniSharp server if not already running. Use a lock to avoid
    starting the server multiple times for the same solution. """
    with self._server_state_lock:
      if self._ServerIsRunning():
        return

      LOGGER.info( 'Starting OmniSharp server' )

      path_to_solutionfile = self._solution_path
      LOGGER.info( 'Loading solution file %s', path_to_solutionfile )

      self._ChooseOmnisharpPort()

      command = [ PATH_TO_OMNISHARP_BINARY,
                  '-p',
                  str( self._omnisharp_port ),
                  '-s',
                  u'{0}'.format( path_to_solutionfile ) ]

      if not utils.OnWindows() and not utils.OnCygwin():
        command.insert( 0, 'mono' )

      if utils.OnCygwin():
        command.extend( [ '--client-path-mode', 'Cygwin' ] )

      solutionfile = os.path.basename( path_to_solutionfile )
      self._filename_stdout = utils.CreateLogfile(
          LOGFILE_FORMAT.format( port = self._omnisharp_port,
                                 sln = solutionfile,
                                 std = 'stdout' ) )
      self._filename_stderr = utils.CreateLogfile(
          LOGFILE_FORMAT.format( port = self._omnisharp_port,
                                 sln = solutionfile,
                                 std = 'stderr' ) )

      with utils.OpenForStdHandle( self._filename_stderr ) as fstderr:
        with utils.OpenForStdHandle( self._filename_stdout ) as fstdout:
          self._omnisharp_phandle = utils.SafePopen(
              command, stdout = fstdout, stderr = fstderr )

      self._solution_path = path_to_solutionfile
Example #59
0
def ShouldEnableTernCompleter():
  """Returns whether or not the tern completer is 'installed'. That is whether
  or not the tern submodule has a 'node_modules' directory. This is pretty much
  the only way we can know if the user added '--js-completer' on
  install or manually ran 'npm install' in the tern submodule directory."""

  if not PATH_TO_NODE:
    LOGGER.warning( 'Not using Tern completer: unable to find node' )
    return False

  LOGGER.info( 'Using node binary from: %s', PATH_TO_NODE )

  installed = os.path.exists( PATH_TO_TERN_BINARY )

  if not installed:
    LOGGER.info( 'Not using Tern completer: not installed at %s',
                 PATH_TO_TERN_BINARY )
    return False

  return True