Skip to content

Commit

Permalink
Merge branch 'develop' into cristi/e2e-with-vsixes
Browse files Browse the repository at this point in the history
  • Loading branch information
CristiCanizales committed Oct 24, 2023
2 parents 2d62aa5 + d5f0f4e commit 260587f
Show file tree
Hide file tree
Showing 19 changed files with 10,901 additions and 5,075 deletions.
15,583 changes: 10,537 additions & 5,046 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions packages/salesforcedx-utils/src/cli/cliCommandExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,13 @@
*/

import { SpawnOptions } from 'child_process';
import * as cross_spawn from 'cross-spawn';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/observable/interval';

import { TELEMETRY_HEADER } from '../constants';
import { CancellationToken, Command } from '../types';
import { CliCommandExecution } from './cliCommandExecution';
import { GlobalCliEnvironment } from './globalCliEnvironment';

// eslint-disable-next-line @typescript-eslint/no-var-requires
const cross_spawn = require('cross-spawn');

export class CliCommandExecutor {
protected static patchEnv(
options: SpawnOptions,
Expand Down
7 changes: 7 additions & 0 deletions packages/salesforcedx-vscode-apex/src/apexErrorHandler.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/*
* Copyright (c) 2023, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

import { EventEmitter } from 'events';
import {
CloseAction,
Expand Down
19 changes: 13 additions & 6 deletions packages/salesforcedx-vscode-apex/src/apexLanguageClient.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import {
LanguageClient,
LanguageClientOptions,
ServerOptions
} from 'vscode-languageclient/node';
/*
* Copyright (c) 2023, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

import { LanguageClient, LanguageClientOptions, ServerOptions } from 'vscode-languageclient/node';
import { ApexErrorHandler } from './apexErrorHandler';

export class ApexLanguageClient extends LanguageClient {
private _errorHandler: ApexErrorHandler | undefined;
public constructor(
id: string,
name: string,
serverOptions: ServerOptions,
private serverOptions: ServerOptions,
clientOptions: LanguageClientOptions,
forceDebug?: boolean
) {
Expand All @@ -21,4 +24,8 @@ export class ApexLanguageClient extends LanguageClient {
public get errorHandler(): ApexErrorHandler | undefined {
return this._errorHandler;
}

public async stop(): Promise<void> {
await super.stop();
}
}
4 changes: 4 additions & 0 deletions packages/salesforcedx-vscode-apex/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@ export const FAIL_RESULT = 'Fail';
export const SKIP_RESULT = 'Skip';

export const APEX_TESTS = 'ApexTests';
export const UBER_JAR_NAME = 'apex-jorje-lsp.jar';
export const APEX_LSP_STARTUP = 'apexLSPStartup';
export const APEX_LSP_ORPHAN = 'apexLSPOrphan';
export const POWERSHELL_NOT_FOUND = 'Powershell not found';
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import {
Uri,
workspace
} from 'vscode';
import { Middleware } from 'vscode-languageclient';
import ProtocolCompletionItem from 'vscode-languageclient/lib/common/protocolCompletionItem';

import { Middleware } from 'vscode-languageclient/node';

const SOQL_SPECIAL_COMPLETION_ITEM_LABEL = '_SOQL_';

const virtualDocumentContents = new Map<string, string>();
Expand Down Expand Up @@ -83,6 +84,7 @@ function getSOQLVirtualContent(
}

export const soqlMiddleware: Middleware = {
// @ts-ignore
provideCompletionItem: async (document, position, context, token, next) => {
const apexCompletionItems = await next(document, position, context, token);
if (!apexCompletionItems) {
Expand Down
12 changes: 8 additions & 4 deletions packages/salesforcedx-vscode-apex/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import { getTestResultsFolder } from '@salesforce/salesforcedx-utils-vscode';
import * as path from 'path';
import * as vscode from 'vscode';
import { State } from 'vscode-languageclient';
import { ApexLanguageClient } from './apexLanguageClient';
import ApexLSPStatusBarItem from './apexLspStatusBarItem';
import { CodeCoverage, StatusBarToggle } from './codecoverage';
Expand All @@ -28,17 +27,18 @@ import {
forceApexTestSuiteRun,
forceLaunchApexReplayDebuggerWithCurrentFile
} from './commands';
import { LSP_ERR, SET_JAVA_DOC_LINK } from './constants';
import { SET_JAVA_DOC_LINK } from './constants';
import { workspaceContext } from './context';
import * as languageServer from './languageServer';
import {languageServerOrphanHandler as lsoh} from './languageServerOrphanHandler';
import {
ClientStatus,
enableJavaDocSymbols,
getApexTests,
getExceptionBreakpointInfo,
getLineBreakpointInfo,
languageClientUtils
} from './languageClientUtils';
import * as languageServer from './languageServer';
} from './languageUtils';
import { nls } from './messages';
import { telemetryService } from './telemetry';
import { getTestOutlineProvider } from './views/testOutlineProvider';
Expand Down Expand Up @@ -314,7 +314,11 @@ async function createLanguageClient(extensionContext: vscode.ExtensionContext) {
}

languageClientUtils.setClientInstance(languageClient);

void lsoh.resolveAnyFoundOrphanLanguageServers();

await languageClient!.start();

const startTime = telemetryService.getEndHRTime(langClientHRStart);
telemetryService.sendEventData('apexLSPStartup', undefined, {
activationTime: startTime
Expand Down
9 changes: 2 additions & 7 deletions packages/salesforcedx-vscode-apex/src/languageServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,15 @@

import * as path from 'path';
import * as vscode from 'vscode';
import {
LanguageClientOptions,
RevealOutputChannelOn
} from 'vscode-languageclient';
import { Executable } from 'vscode-languageclient/node';
import { Executable, LanguageClientOptions, RevealOutputChannelOn } from 'vscode-languageclient/node';
import { ApexErrorHandler } from './apexErrorHandler';
import { ApexLanguageClient } from './apexLanguageClient';
import { LSP_ERR } from './constants';
import { LSP_ERR, UBER_JAR_NAME } from './constants';
import { soqlMiddleware } from './embeddedSoql';
import { nls } from './messages';
import * as requirements from './requirements';
import { telemetryService } from './telemetry';

const UBER_JAR_NAME = 'apex-jorje-lsp.jar';
const JDWP_DEBUG_PORT = 2739;
const APEX_LANGUAGE_SERVER_MAIN = 'apex.jorje.lsp.ApexLanguageServerLauncher';
const SUSPEND_LANGUAGE_SERVER_STARTUP =
Expand Down
144 changes: 144 additions & 0 deletions packages/salesforcedx-vscode-apex/src/languageServerOrphanHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@

import { Column, Row, Table } from '@salesforce/salesforcedx-utils-vscode';
import * as vscode from 'vscode';
import { channelService } from './channels';
import { APEX_LSP_ORPHAN } from './constants';
import { languageServerUtils as lsu, ProcessDetail } from './languageUtils';
import { nls } from './messages';
import { telemetryService } from './telemetry';

export const ADVICE = nls.localize('orphan_process_advice');
export const YES = nls.localize('yes');
export const CANCEL = nls.localize('cancel');
export const SHOW_PROCESSES = nls.localize('terminate_show_processes');
export const TERMINATE_PROCESSES_BTN = nls.localize('terminate_processes');
export const SHOW_PROCESSES_BTN = nls.localize('terminate_show_processes');
export const DISMISSED_DEFAULT = 'dismissed';
export const PROCESS_ID = nls.localize('process_id');
export const PROCESS_PARENT_ID = nls.localize('parent_process_id');
export const COMMAND = nls.localize('process_command');

// these messages contain replaceable parameters, cannot localize yet
export const CONFIRM = 'terminate_processes_confirm';
export const TERMINATE_ORPHANED_PROCESSES = 'terminate_orphaned_language_server_instances';
export const TERMINATED_PROCESS = 'terminated_orphaned_process';
export const TERMINATE_FAILED = 'terminate_failed';

async function resolveAnyFoundOrphanLanguageServers(): Promise<void> {
const orphanedProcesses = lsu.findAndCheckOrphanedProcesses();
if (orphanedProcesses.length > 0) {
if (await getResolutionForOrphanProcesses(orphanedProcesses)) {
telemetryService.sendEventData(APEX_LSP_ORPHAN, undefined, { orphanCount: orphanedProcesses.length, didTerminate: 1 });
for (const processInfo of orphanedProcesses) {
try {
await lsu.terminateProcess(processInfo.pid);
telemetryService.sendEventData(APEX_LSP_ORPHAN, undefined, { terminateSuccessful: 1 });
showProcessTerminated(processInfo);
} catch (err) {
showTerminationFailed(processInfo, err);
telemetryService.sendException(
APEX_LSP_ORPHAN,
typeof err === 'string' ? err : err?.message ? err.message : 'unknown');
}
}
} else {
telemetryService.sendEventData(APEX_LSP_ORPHAN, undefined, { orphanCount: orphanedProcesses.length, didTerminate: 0 });
}
}
}

/**
* Ask the user how to resolve found orphaned language server instances
* @param orphanedProcesses
* @returns boolean
*/
async function getResolutionForOrphanProcesses(orphanedProcesses: ProcessDetail[]): Promise<boolean> {
const orphanedCount = orphanedProcesses.length;

if (orphanedCount === 0) {
return false;
}

let choice: string | undefined;
do {
choice = await vscode.window.showWarningMessage(
nls.localize(
TERMINATE_ORPHANED_PROCESSES,
orphanedCount
),
TERMINATE_PROCESSES_BTN,
SHOW_PROCESSES_BTN
) ?? DISMISSED_DEFAULT;

if (requestsTermination(choice) && await terminationConfirmation(orphanedCount)) {
return true;
} else if (showProcesses(choice)) {
showOrphansInChannel(orphanedProcesses);
}
} while (!choice || showProcesses(choice));
return false;
}

function showOrphansInChannel(orphanedProcesses: ProcessDetail[]) {
const columns: Column[] = [
{ key: 'pid', label: PROCESS_ID },
{ key: 'ppid', label: PROCESS_PARENT_ID },
{ key: 'command', label: COMMAND }
];

const rows: Row[] = orphanedProcesses.map(processInfo => {
return {
pid: processInfo.pid.toString(),
ppid: processInfo.ppid.toString(),
// split command into equal chunks no more than 70 characters long
command: processInfo.command.length <= 70 ? processInfo.command : processInfo.command.match(/.{1,70}/g)?.join('\n') ?? ''
};
});

const table: Table = new Table();
const tableString = table.createTable(rows, columns);

channelService.showChannelOutput();
channelService.appendLine(ADVICE);
channelService.appendLine('');
channelService.appendLine(tableString);
}

async function terminationConfirmation(orphanedCount: number): Promise<boolean> {
const choice = await vscode.window.showWarningMessage(
nls.localize(
CONFIRM,
orphanedCount
),
YES,
CANCEL
);
return choice === YES;
}

function requestsTermination(choice: string | undefined): boolean {
return choice === TERMINATE_PROCESSES_BTN;
}

function showProcesses(choice: string): boolean {
return choice === SHOW_PROCESSES_BTN;
}

function showProcessTerminated(processDetail: ProcessDetail): void {
channelService.appendLine(nls.localize(TERMINATED_PROCESS, processDetail.pid));
}

function showTerminationFailed(processInfo: ProcessDetail, err: any): void {
channelService.appendLine(nls.localize(TERMINATE_FAILED, processInfo.pid, err.message));
}

export const languageServerOrphanHandler = {
getResolutionForOrphanProcesses,
requestsTermination,
resolveAnyFoundOrphanLanguageServers,
showOrphansInChannel,
showProcessTerminated,
showProcesses,
showTerminationFailed,
terminationConfirmation
};
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ export {
} from './languageClientUtils';

export { enableJavaDocSymbols } from './javaDocSymbols';

export { languageServerUtils, ProcessDetail } from './languageServerUtils';
Loading

0 comments on commit 260587f

Please sign in to comment.