[Code] api for lsp initialize state (#39425) (#39551)

* [Code] added a api for lsp initialize state

* [Code] fix hang if lang-server exited during indexing
This commit is contained in:
Yulong 2019-06-26 14:17:03 +08:00 committed by GitHub
parent 7a6a1fb50f
commit ff3d39dd94
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 59 additions and 8 deletions

View file

@ -23,6 +23,7 @@ import { InstallManager } from './install_manager';
import { ILanguageServerLauncher } from './language_server_launcher';
import { enabledLanguageServers, LanguageServerDefinition } from './language_servers';
import { ILanguageServerHandler } from './proxy';
import { WorkspaceStatus } from './request_expander';
export interface LanguageServerHandlerMap {
[workspaceUri: string]: Promise<ILanguageServerHandler>;
@ -254,4 +255,30 @@ export class LanguageServerController implements ILanguageServerHandler {
throw new ResponseError(UnknownFileLanguage, `unsupported language ${lang}`);
}
}
public async initializeState(workspacePath: string) {
const result: { [lang: string]: WorkspaceStatus } = {};
for (const languageServer of this.languageServers) {
if (languageServer.languageServerHandlers) {
if (languageServer.builtinWorkspaceFolders) {
const handler = await (languageServer.languageServerHandlers as Promise<
ILanguageServerHandler
>);
result[languageServer.definition.name] = (await handler.initializeState!(
workspacePath
)) as WorkspaceStatus;
} else {
const handlers = languageServer.languageServerHandlers as LanguageServerHandlerMap;
const realPath = fs.realpathSync(workspacePath);
const handler = handlers[realPath];
if (handler) {
result[languageServer.definition.name] = (await handler).initializeState!(
workspacePath
) as WorkspaceStatus;
}
}
}
}
return result;
}
}

View file

@ -85,4 +85,9 @@ export class LspService {
public languageServerStatus(lang: string): LanguageServerStatus {
return this.controller.status(lang);
}
public async initializeState(repoUri: string, revision: string) {
const workspacePath = await this.workspaceHandler.revisionDir(repoUri, revision);
return this.controller.initializeState(workspacePath);
}
}

View file

@ -28,13 +28,16 @@ import { LspRequest } from '../../model';
import { Logger } from '../log';
import { LspOptions } from '../server_options';
import { InternalError, RequestCancelled } from '../../common/lsp_error_codes';
import { InitializeOptions } from './request_expander';
import { InitializeOptions, WorkspaceStatus } from './request_expander';
export interface ILanguageServerHandler {
lastAccess?: number;
handleRequest(request: LspRequest): Promise<ResponseMessage>;
exit(): Promise<any>;
unloadWorkspace(workspaceDir: string): Promise<void>;
initializeState?(
workspaceDir: string
): Promise<{ [lang: string]: WorkspaceStatus }> | WorkspaceStatus;
}
export class LanguageServerProxy implements ILanguageServerHandler {
@ -78,7 +81,6 @@ export class LanguageServerProxy implements ILanguageServerHandler {
} else {
conn.sendNotification(request.method, ...params);
}
return response;
}

View file

@ -28,10 +28,10 @@ interface Job {
startTime: number;
}
enum WorkspaceStatus {
Uninitialized,
Initializing,
Initialized,
export enum WorkspaceStatus {
Uninitialized = 'Uninitialized',
Initializing = 'Initializing',
Initialized = 'Initialized',
}
interface Workspace {
@ -300,7 +300,7 @@ export class RequestExpander implements ILanguageServerHandler {
}
private updateWorkspace(workspacePath: string) {
this.getWorkspace(workspacePath).status = Date.now();
this.getWorkspace(workspacePath).lastAccess = Date.now();
}
private hasWorkspacePath(workspacePath: string) {
@ -328,4 +328,11 @@ export class RequestExpander implements ILanguageServerHandler {
}
return ws;
}
initializeState(workspaceDir: string): WorkspaceStatus {
if (this.hasWorkspacePath(workspaceDir)) {
return this.getWorkspace(workspaceDir).status;
}
return WorkspaceStatus.Uninitialized;
}
}

View file

@ -356,7 +356,7 @@ export class WorkspaceHandler {
return false;
}
private async revisionDir(repositoryUri: string, revision: string) {
public async revisionDir(repositoryUri: string, revision: string) {
return path.join(await this.workspaceDir(repositoryUri), revision);
}

View file

@ -40,6 +40,16 @@ export function lspRoute(
serverOptions: ServerOptions
) {
const log = new Logger(server.server);
server.route({
path: '/api/code/repo/{uri*3}/{ref}/lspstate',
method: 'GET',
async handler(req) {
const { uri, ref } = req.params;
return lspService.initializeState(uri, ref);
},
});
server.route({
path: '/api/code/lsp/textDocument/{method}',
async handler(req, h: hapi.ResponseToolkit) {