Skip to content

Fix linting in debugger #20152

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Nov 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 1 addition & 32 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -108,17 +108,6 @@ src/test/common/interpreterPathService.unit.test.ts

src/test/pythonFiles/formatting/dummy.ts

src/test/debugger/extension/configuration/debugConfigurationService.unit.test.ts
src/test/debugger/extension/configuration/providers/fileLaunch.unit.test.ts
src/test/debugger/extension/configuration/providers/providerFactory.unit.test.ts
src/test/debugger/extension/configuration/providers/pidAttach.unit.test.ts
src/test/debugger/extension/configuration/resolvers/base.unit.test.ts
src/test/debugger/extension/configuration/resolvers/common.ts
src/test/debugger/extension/configuration/resolvers/attach.unit.test.ts
src/test/debugger/extension/configuration/resolvers/launch.unit.test.ts
src/test/debugger/extension/configuration/launch.json/updaterServer.unit.test.ts
src/test/debugger/extension/configuration/launch.json/completionProvider.unit.test.ts
src/test/debugger/extension/configuration/launch.json/interpreterPathCommand.unit.test.ts
src/test/debugger/extension/banner.unit.test.ts
src/test/debugger/extension/adapter/adapter.test.ts
src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts
Expand Down Expand Up @@ -272,38 +261,18 @@ src/client/common/process/pythonProcess.ts
src/client/common/process/pythonEnvironment.ts
src/client/common/process/decoder.ts

src/client/debugger/extension/configuration/providers/moduleLaunch.ts
src/client/debugger/extension/configuration/providers/fastapiLaunch.ts
src/client/debugger/extension/configuration/providers/flaskLaunch.ts
src/client/debugger/extension/configuration/providers/fileLaunch.ts
src/client/debugger/extension/configuration/providers/remoteAttach.ts
src/client/debugger/extension/configuration/providers/djangoLaunch.ts
src/client/debugger/extension/configuration/providers/providerFactory.ts
src/client/debugger/extension/configuration/providers/pyramidLaunch.ts
src/client/debugger/extension/configuration/providers/pidAttach.ts
src/client/debugger/extension/configuration/resolvers/base.ts
src/client/debugger/extension/configuration/resolvers/helper.ts
src/client/debugger/extension/configuration/resolvers/launch.ts
src/client/debugger/extension/configuration/resolvers/attach.ts
src/client/debugger/extension/configuration/debugConfigurationService.ts
src/client/debugger/extension/configuration/launch.json/updaterService.ts
src/client/debugger/extension/configuration/launch.json/interpreterPathCommand.ts
src/client/debugger/extension/configuration/launch.json/completionProvider.ts
src/client/debugger/extension/banner.ts
src/client/debugger/extension/serviceRegistry.ts

src/client/debugger/extension/adapter/remoteLaunchers.ts
src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts
src/client/debugger/extension/adapter/factory.ts
src/client/debugger/extension/adapter/activator.ts
src/client/debugger/extension/adapter/logging.ts
src/client/debugger/extension/types.ts
src/client/debugger/extension/hooks/eventHandlerDispatcher.ts
src/client/debugger/extension/hooks/childProcessAttachService.ts
src/client/debugger/extension/attachQuickPick/wmicProcessParser.ts
src/client/debugger/extension/attachQuickPick/factory.ts
src/client/debugger/extension/attachQuickPick/psProcessParser.ts
src/client/debugger/extension/attachQuickPick/picker.ts
src/client/debugger/extension/helpers/protocolParser.ts

src/client/application/serviceRegistry.ts
src/client/application/diagnostics/surceMapSupportService.ts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { IDebugConfigurationResolver } from './types';
@injectable()
export class PythonDebugConfigurationService implements IDebugConfigurationService {
private cacheDebugConfig: DebugConfiguration | undefined = undefined;

constructor(
@inject(IDebugConfigurationResolver)
@named('attach')
Expand All @@ -47,13 +48,12 @@ export class PythonDebugConfigurationService implements IDebugConfigurationServi

// Disabled until configuration issues are addressed by VS Code. See #4007
const multiStep = this.multiStepFactory.create<DebugConfigurationState>();
await multiStep.run((input, s) => this.pickDebugConfiguration(input, s), state);
await multiStep.run((input, s) => PythonDebugConfigurationService.pickDebugConfiguration(input, s), state);

if (Object.keys(state.config).length === 0) {
return;
} else {
if (Object.keys(state.config).length !== 0) {
return [state.config as DebugConfiguration];
}
return undefined;
}

public async resolveDebugConfiguration(
Expand All @@ -67,7 +67,8 @@ export class PythonDebugConfigurationService implements IDebugConfigurationServi
debugConfiguration as AttachRequestArguments,
token,
);
} else if (debugConfiguration.request === 'test') {
}
if (debugConfiguration.request === 'test') {
// `"request": "test"` is now deprecated. But some users might have it in their
// launch config. We get here if they triggered it using F5 or start with debugger.
throw Error(
Expand All @@ -80,9 +81,10 @@ export class PythonDebugConfigurationService implements IDebugConfigurationServi
} else {
const configs = await this.provideDebugConfigurations(folder, token);
if (configs === undefined) {
return;
return undefined;
}
if (Array.isArray(configs) && configs.length === 1) {
// eslint-disable-next-line prefer-destructuring
debugConfiguration = configs[0];
}
this.cacheDebugConfig = cloneDeep(debugConfiguration);
Expand All @@ -107,7 +109,8 @@ export class PythonDebugConfigurationService implements IDebugConfigurationServi
return debugConfiguration.request === 'attach' ? resolve(this.attachResolver) : resolve(this.launchResolver);
}

protected async pickDebugConfiguration(
// eslint-disable-next-line consistent-return
protected static async pickDebugConfiguration(
input: MultiStepInput<DebugConfigurationState>,
state: DebugConfigurationState,
): Promise<InputStep<DebugConfigurationState> | void> {
Expand Down Expand Up @@ -178,7 +181,7 @@ export class PythonDebugConfigurationService implements IDebugConfigurationServi
title: DebugConfigStrings.selectConfiguration.title,
placeholder: DebugConfigStrings.selectConfiguration.placeholder,
activeItem: items[0],
items: items,
items,
});
if (pick) {
const pickedDebugConfiguration = debugConfigurations.get(pick.type)!;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ enum JsonLanguages {
@injectable()
export class LaunchJsonCompletionProvider implements CompletionItemProvider, IExtensionSingleActivationService {
public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false };

constructor(
@inject(ILanguageService) private readonly languageService: ILanguageService,
@inject(IDisposableRegistry) private readonly disposableRegistry: IDisposableRegistry,
) {}

public async activate(): Promise<void> {
this.disposableRegistry.push(
this.languageService.registerCompletionItemProvider({ language: JsonLanguages.json }, this),
Expand All @@ -41,12 +43,14 @@ export class LaunchJsonCompletionProvider implements CompletionItemProvider, IEx
this.languageService.registerCompletionItemProvider({ language: JsonLanguages.jsonWithComments }, this),
);
}

// eslint-disable-next-line class-methods-use-this
public async provideCompletionItems(
document: TextDocument,
position: Position,
token: CancellationToken,
): Promise<CompletionItem[]> {
if (!this.canProvideCompletions(document, position)) {
if (!LaunchJsonCompletionProvider.canProvideCompletions(document, position)) {
return [];
}

Expand All @@ -66,7 +70,8 @@ export class LaunchJsonCompletionProvider implements CompletionItemProvider, IEx
},
];
}
public canProvideCompletions(document: TextDocument, position: Position) {

public static canProvideCompletions(document: TextDocument, position: Position): boolean {
if (path.basename(document.uri.fsPath) !== 'launch.json') {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,34 @@ import { IInterpreterService } from '../../../../interpreter/contracts';
@injectable()
export class InterpreterPathCommand implements IExtensionSingleActivationService {
public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false };

constructor(
@inject(ICommandManager) private readonly commandManager: ICommandManager,
@inject(IInterpreterService) private readonly interpreterService: IInterpreterService,
@inject(IDisposableRegistry) private readonly disposables: IDisposable[],
) {}

public async activate() {
public async activate(): Promise<void> {
this.disposables.push(
this.commandManager.registerCommand(Commands.GetSelectedInterpreterPath, (args) => {
return this._getSelectedInterpreterPath(args);
}),
this.commandManager.registerCommand(Commands.GetSelectedInterpreterPath, (args) =>
this._getSelectedInterpreterPath(args),
),
);
}

public async _getSelectedInterpreterPath(args: { workspaceFolder: string } | string[]): Promise<string> {
// If `launch.json` is launching this command, `args.workspaceFolder` carries the workspaceFolder
// If `tasks.json` is launching this command, `args[1]` carries the workspaceFolder
const workspaceFolder = 'workspaceFolder' in args ? args.workspaceFolder : args[1] ? args[1] : undefined;
let workspaceFolder;
if ('workspaceFolder' in args) {
workspaceFolder = args.workspaceFolder;
} else if (args[1]) {
const [, second] = args;
workspaceFolder = second;
} else {
workspaceFolder = undefined;
}

let workspaceFolderUri;
try {
workspaceFolderUri = workspaceFolder ? Uri.parse(workspaceFolder) : undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,156 +4,24 @@
'use strict';

import { inject, injectable } from 'inversify';
import { createScanner, parse, SyntaxKind } from 'jsonc-parser';
import { CancellationToken, DebugConfiguration, Position, Range, TextDocument, WorkspaceEdit } from 'vscode';
import { IExtensionSingleActivationService } from '../../../../activation/types';
import { ICommandManager, IDocumentManager, IWorkspaceService } from '../../../../common/application/types';
import { IDisposableRegistry } from '../../../../common/types';
import { noop } from '../../../../common/utils/misc';
import { captureTelemetry } from '../../../../telemetry';
import { EventName } from '../../../../telemetry/constants';
import { IDebugConfigurationService } from '../../types';

type PositionOfCursor = 'InsideEmptyArray' | 'BeforeItem' | 'AfterItem';
type PositionOfComma = 'BeforeCursor';

export class LaunchJsonUpdaterServiceHelper {
constructor(
private readonly commandManager: ICommandManager,
private readonly workspace: IWorkspaceService,
private readonly documentManager: IDocumentManager,
private readonly configurationProvider: IDebugConfigurationService,
) {}
@captureTelemetry(EventName.DEBUGGER_CONFIGURATION_PROMPTS_IN_LAUNCH_JSON)
public async selectAndInsertDebugConfig(
document: TextDocument,
position: Position,
token: CancellationToken,
): Promise<void> {
if (this.documentManager.activeTextEditor && this.documentManager.activeTextEditor.document === document) {
const folder = this.workspace.getWorkspaceFolder(document.uri);
const configs = await this.configurationProvider.provideDebugConfigurations!(folder, token);

if (!token.isCancellationRequested && Array.isArray(configs) && configs.length > 0) {
// Always use the first available debug configuration.
await this.insertDebugConfiguration(document, position, configs[0]);
}
}
}
/**
* Inserts the debug configuration into the document.
* Invokes the document formatter to ensure JSON is formatted nicely.
* @param {TextDocument} document
* @param {Position} position
* @param {DebugConfiguration} config
* @returns {Promise<void>}
* @memberof LaunchJsonCompletionItemProvider
*/
public async insertDebugConfiguration(
document: TextDocument,
position: Position,
config: DebugConfiguration,
): Promise<void> {
const cursorPosition = this.getCursorPositionInConfigurationsArray(document, position);
if (!cursorPosition) {
return;
}
const commaPosition = this.isCommaImmediatelyBeforeCursor(document, position) ? 'BeforeCursor' : undefined;
const formattedJson = this.getTextForInsertion(config, cursorPosition, commaPosition);
const workspaceEdit = new WorkspaceEdit();
workspaceEdit.insert(document.uri, position, formattedJson);
await this.documentManager.applyEdit(workspaceEdit);
this.commandManager.executeCommand('editor.action.formatDocument').then(noop, noop);
}
/**
* Gets the string representation of the debug config for insertion in the document.
* Adds necessary leading or trailing commas (remember the text is added into an array).
* @param {DebugConfiguration} config
* @param {PositionOfCursor} cursorPosition
* @param {PositionOfComma} [commaPosition]
* @returns
* @memberof LaunchJsonCompletionItemProvider
*/
public getTextForInsertion(
config: DebugConfiguration,
cursorPosition: PositionOfCursor,
commaPosition?: PositionOfComma,
) {
const json = JSON.stringify(config);
if (cursorPosition === 'AfterItem') {
// If we already have a comma immediatley before the cursor, then no need of adding a comma.
return commaPosition === 'BeforeCursor' ? json : `,${json}`;
}
if (cursorPosition === 'BeforeItem') {
return `${json},`;
}
return json;
}
public getCursorPositionInConfigurationsArray(
document: TextDocument,
position: Position,
): PositionOfCursor | undefined {
if (this.isConfigurationArrayEmpty(document)) {
return 'InsideEmptyArray';
}
const scanner = createScanner(document.getText(), true);
scanner.setPosition(document.offsetAt(position));
const nextToken = scanner.scan();
if (nextToken === SyntaxKind.CommaToken || nextToken === SyntaxKind.CloseBracketToken) {
return 'AfterItem';
}
if (nextToken === SyntaxKind.OpenBraceToken) {
return 'BeforeItem';
}
}
public isConfigurationArrayEmpty(document: TextDocument): boolean {
const configuration = parse(document.getText(), [], { allowTrailingComma: true, disallowComments: false }) as {
configurations: [];
};
return (
!configuration || !Array.isArray(configuration.configurations) || configuration.configurations.length === 0
);
}
public isCommaImmediatelyBeforeCursor(document: TextDocument, position: Position) {
const line = document.lineAt(position.line);
// Get text from start of line until the cursor.
const currentLine = document.getText(new Range(line.range.start, position));
if (currentLine.trim().endsWith(',')) {
return true;
}
// If there are other characters, then don't bother.
if (currentLine.trim().length !== 0) {
return false;
}

// Keep walking backwards until we hit a non-comma character or a comm character.
let startLineNumber = position.line - 1;
while (startLineNumber > 0) {
const lineText = document.lineAt(startLineNumber).text;
if (lineText.trim().endsWith(',')) {
return true;
}
// If there are other characters, then don't bother.
if (lineText.trim().length !== 0) {
return false;
}
startLineNumber -= 1;
continue;
}
return false;
}
}
import { LaunchJsonUpdaterServiceHelper } from './updaterServiceHelper';

@injectable()
export class LaunchJsonUpdaterService implements IExtensionSingleActivationService {
public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false };

constructor(
@inject(ICommandManager) private readonly commandManager: ICommandManager,
@inject(IDisposableRegistry) private readonly disposableRegistry: IDisposableRegistry,
@inject(IWorkspaceService) private readonly workspace: IWorkspaceService,
@inject(IDocumentManager) private readonly documentManager: IDocumentManager,
@inject(IDebugConfigurationService) private readonly configurationProvider: IDebugConfigurationService,
) {}

public async activate(): Promise<void> {
const handler = new LaunchJsonUpdaterServiceHelper(
this.commandManager,
Expand Down
Loading