diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 508eae4c5ddc..f27b792c337d 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -4,6 +4,7 @@ "recommendations": [ "ms-vscode.vscode-typescript-tslint-plugin", "editorconfig.editorconfig", - "esbenp.prettier-vscode" + "esbenp.prettier-vscode", + "dbaeumer.vscode-eslint" ] } diff --git a/src/client/activation/languageServer/analysisOptions.ts b/src/client/activation/languageServer/analysisOptions.ts index 21e263d08a42..c9e2806b5154 100644 --- a/src/client/activation/languageServer/analysisOptions.ts +++ b/src/client/activation/languageServer/analysisOptions.ts @@ -56,7 +56,7 @@ export class DotNetLanguageServerAnalysisOptions extends LanguageServerAnalysisO if ( workspaceFolder && Array.isArray(this.workspace.workspaceFolders) && - this.workspace.workspaceFolders!.length > 1 + this.workspace.workspaceFolders.length > 1 ) { filters[0].pattern = `${workspaceFolder.uri.fsPath}/**/*`; } diff --git a/src/client/common/application/debugSessionTelemetry.ts b/src/client/common/application/debugSessionTelemetry.ts index 47aac873a835..692ded155a13 100644 --- a/src/client/common/application/debugSessionTelemetry.ts +++ b/src/client/common/application/debugSessionTelemetry.ts @@ -13,6 +13,10 @@ import { IDisposableRegistry } from '../types'; import { StopWatch } from '../utils/stopWatch'; import { IDebugService } from './types'; +// tslint:disable-next-line no-any +function isResponse(a: any): a is DebugProtocol.Response { + return a.type === 'response'; +} class TelemetryTracker implements DebugAdapterTracker { private timer = new StopWatch(); private readonly trigger: TriggerType = 'launch'; @@ -28,26 +32,25 @@ class TelemetryTracker implements DebugAdapterTracker { this.sendTelemetry(EventName.DEBUG_SESSION_START); } - // tslint:disable-next-line:no-any - public onDidSendMessage(message: DebugProtocol.ProtocolMessage) { - if (message.type === 'response') { - const response = message as DebugProtocol.Response; - if (response.command === 'configurationDone') { + // tslint:disable-next-line no-any + public onDidSendMessage(message: any): void { + if (isResponse(message)) { + if (message.command === 'configurationDone') { // "configurationDone" response is sent immediately after user code starts running. this.sendTelemetry(EventName.DEBUG_SESSION_USER_CODE_RUNNING); } } } - public onWillStopSession() { + public onWillStopSession(): void { this.sendTelemetry(EventName.DEBUG_SESSION_STOP); } - public onError?(_error: Error) { + public onError?(_error: Error): void { this.sendTelemetry(EventName.DEBUG_SESSION_ERROR); } - private sendTelemetry(eventName: EventName) { + private sendTelemetry(eventName: EventName): void { if (eventName === EventName.DEBUG_SESSION_START) { this.timer.reset(); } diff --git a/src/client/common/cancellation.ts b/src/client/common/cancellation.ts index 601ac933979d..a9d67de643f2 100644 --- a/src/client/common/cancellation.ts +++ b/src/client/common/cancellation.ts @@ -33,6 +33,7 @@ export function createPromiseFromCancellation(options: { return; } const complete = () => { + // NOSONAR if (options.token!.isCancellationRequested) { if (options.cancelAction === 'resolve') { return resolve(options.defaultValue); diff --git a/src/client/common/installer/condaInstaller.ts b/src/client/common/installer/condaInstaller.ts index 4eb573eed4a3..4fc2cc7f2333 100644 --- a/src/client/common/installer/condaInstaller.ts +++ b/src/client/common/installer/condaInstaller.ts @@ -69,7 +69,7 @@ export class CondaInstaller extends ModuleInstaller { if (info && info.name) { // If we have the name of the conda environment, then use that. args.push('--name'); - args.push(info.name!.toCommandArgument()); + args.push(info.name.toCommandArgument()); } else if (info && info.path) { // Else provide the full path to the environment path. args.push('--prefix'); diff --git a/src/client/common/terminal/activator/base.ts b/src/client/common/terminal/activator/base.ts index 27ad3d6ad5d5..65e060892bb3 100644 --- a/src/client/common/terminal/activator/base.ts +++ b/src/client/common/terminal/activator/base.ts @@ -28,7 +28,7 @@ export class BaseTerminalActivator implements ITerminalActivator { ); let activated = false; if (activationCommands) { - for (const command of activationCommands!) { + for (const command of activationCommands) { terminal.show(options?.preserveFocus); terminal.sendText(command); await this.waitForCommandToProcess(terminalShellType); diff --git a/src/client/debugger/extension/hooks/childProcessAttachHandler.ts b/src/client/debugger/extension/hooks/childProcessAttachHandler.ts index 9a3a7bda4935..7656ac9f527d 100644 --- a/src/client/debugger/extension/hooks/childProcessAttachHandler.ts +++ b/src/client/debugger/extension/hooks/childProcessAttachHandler.ts @@ -34,7 +34,7 @@ export class ChildProcessAttachEventHandler implements IDebugSessionEventHandler event.event === DebuggerEvents.PtvsdAttachToSubprocess || event.event === DebuggerEvents.DebugpyAttachToSubprocess ) { - data = event.body! as AttachRequestArguments & DebugConfiguration; + data = event.body as AttachRequestArguments & DebugConfiguration; } else { return; } diff --git a/src/client/pythonEnvironments/discovery/locators/services/baseVirtualEnvService.ts b/src/client/pythonEnvironments/discovery/locators/services/baseVirtualEnvService.ts index 121ffe0152b9..cdbc266ae9c1 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/baseVirtualEnvService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/baseVirtualEnvService.ts @@ -61,7 +61,7 @@ export class BaseVirtualEnvService extends CacheableLocatorService { )) .then((interpreters) => interpreters.filter( (interpreter) => !!interpreter, - ).map((interpreter) => interpreter!)) + ).map((interpreter) => interpreter!)) // NOSONAR .catch((err) => { traceError('Python Extension (lookForInterpretersInVenvs):', err); // Ignore exceptions. diff --git a/src/client/pythonEnvironments/discovery/locators/services/condaService.ts b/src/client/pythonEnvironments/discovery/locators/services/condaService.ts index e8dcd1d44f89..34163fccfb8e 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/condaService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/condaService.ts @@ -25,7 +25,8 @@ const untildify: (value: string) => string = require('untildify'); // This glob pattern will match all of the following: // ~/anaconda/bin/conda, ~/anaconda3/bin/conda, ~/miniconda/bin/conda, ~/miniconda3/bin/conda -// /usr/share/anaconda/bin/conda, /usr/share/anaconda3/bin/conda, /usr/share/miniconda/bin/conda, /usr/share/miniconda3/bin/conda +// /usr/share/anaconda/bin/conda, /usr/share/anaconda3/bin/conda, /usr/share/miniconda/bin/conda, +// /usr/share/miniconda3/bin/conda const condaGlobPathsForLinuxMac = [ untildify('~/opt/*conda*/bin/conda'), @@ -62,6 +63,11 @@ interface IComponent { */ @injectable() export class CondaService implements ICondaService { + public get condaEnvironmentsFile(): string | undefined { + const homeDir = this.platform.isWindows ? process.env.USERPROFILE : process.env.HOME || process.env.HOMEPATH; + return homeDir ? path.join(homeDir, '.conda', 'environments.txt') : undefined; + } + private condaFile?: Promise; private isAvailable: boolean | undefined; @@ -83,9 +89,30 @@ export class CondaService implements ICondaService { this.addCondaPathChangedHandler(); } - public get condaEnvironmentsFile(): string | undefined { - const homeDir = this.platform.isWindows ? process.env.USERPROFILE : process.env.HOME || process.env.HOMEPATH; - return homeDir ? path.join(homeDir, '.conda', 'environments.txt') : undefined; + /** + * Return the highest Python version from the given list. + */ + private static getLatestVersion(interpreters: PythonEnvironment[]): PythonEnvironment | undefined { + const sortedInterpreters = interpreters.slice(); + // tslint:disable-next-line:no-non-null-assertion + sortedInterpreters.sort((a, b) => (a.version && b.version ? compare(a.version.raw, b.version.raw) : 0)); + if (sortedInterpreters.length > 0) { + return sortedInterpreters[sortedInterpreters.length - 1]; + } + + return undefined; + } + + /** + * Is the given interpreter from conda? + */ + private static detectCondaEnvironment(env: PythonEnvironment): boolean { + return ( + env.envType === EnvironmentType.Conda + || (env.displayName ? env.displayName : '').toUpperCase().indexOf('ANACONDA') >= 0 + || (env.companyDisplayName ? env.companyDisplayName : '').toUpperCase().indexOf('ANACONDA') >= 0 + || (env.companyDisplayName ? env.companyDisplayName : '').toUpperCase().indexOf('CONTINUUM') >= 0 + ); } /** @@ -94,7 +121,7 @@ export class CondaService implements ICondaService { * Called by VS Code to indicate it is done with the resource. */ // tslint:disable-next-line:no-empty - public dispose() {} + public dispose(): void {} // eslint-disable-line /** * Return the path to the "conda file". @@ -116,8 +143,9 @@ export class CondaService implements ICondaService { return this.isAvailable; } return this.getCondaVersion() - .then((version) => (this.isAvailable = version !== undefined)) - .catch(() => (this.isAvailable = false)); + + .then((version) => (this.isAvailable = version !== undefined)) // eslint-disable-line no-return-assign + .catch(() => (this.isAvailable = false)); // eslint-disable-line no-return-assign } /** @@ -143,7 +171,7 @@ export class CondaService implements ICondaService { versionString = stdOut && stdOut.startsWith('conda ') ? stdOut.substring('conda '.length).trim() : stdOut; } if (!versionString) { - return; + return undefined; } const version = parse(versionString, true); if (version) { @@ -157,7 +185,7 @@ export class CondaService implements ICondaService { /** * Can the shell find conda (to run it)? */ - public async isCondaInCurrentPath() { + public async isCondaInCurrentPath(): Promise { const processService = await this.processServiceFactory.create(); return processService .exec('conda', ['--version']) @@ -181,6 +209,7 @@ export class CondaService implements ICondaService { // Failed because either: // 1. conda is not installed. // 2. `conda info --json` has changed signature. + return undefined; } } @@ -212,7 +241,7 @@ export class CondaService implements ICondaService { } const isCondaEnv = await this.isCondaEnvironment(interpreterPath); if (!isCondaEnv) { - return; + return undefined; } let environments = await this.getCondaEnvironments(false); const dir = path.dirname(interpreterPath); @@ -239,6 +268,7 @@ export class CondaService implements ICondaService { // If still not available, then the user created the env after starting vs code. // The only solution is to get the user to re-start vscode. + return undefined; } /** @@ -249,8 +279,7 @@ export class CondaService implements ICondaService { // Global cache. const globalPersistence = this.persistentStateFactory.createGlobalPersistentState<{ data: CondaEnvironmentInfo[] | undefined; - // tslint:disable-next-line:no-any - }>('CONDA_ENVIRONMENTS', undefined as any); + }>('CONDA_ENVIRONMENTS', undefined); if (!ignoreCache && globalPersistence.value) { return globalPersistence.value.data; } @@ -284,6 +313,7 @@ export class CondaService implements ICondaService { // 1. conda is not installed. // 2. `conda env list has changed signature. traceError('Failed to get conda environment list from conda', ex); + return undefined; } } @@ -297,7 +327,9 @@ export class CondaService implements ICondaService { } /** - * Get the conda exe from the path to an interpreter's python. This might be different than the globally registered conda.exe + * Get the conda exe from the path to an interpreter's python. This might be different than the + * globally registered conda.exe. + * * The value is cached for a while. * The only way this can change is if user installs conda into this same environment. * Generally we expect that to happen the other way, the user creates a conda environment with conda in it. @@ -338,30 +370,8 @@ export class CondaService implements ICondaService { if (await this.fileSystem.fileExists(condaPath2)) { return condaPath2; } - } - /** - * Is the given interpreter from conda? - */ - private detectCondaEnvironment(env: PythonEnvironment) { - return ( - env.envType === EnvironmentType.Conda - || (env.displayName ? env.displayName : '').toUpperCase().indexOf('ANACONDA') >= 0 - || (env.companyDisplayName ? env.companyDisplayName : '').toUpperCase().indexOf('ANACONDA') >= 0 - || (env.companyDisplayName ? env.companyDisplayName : '').toUpperCase().indexOf('CONTINUUM') >= 0 - ); - } - - /** - * Return the highest Python version from the given list. - */ - private getLatestVersion(interpreters: PythonEnvironment[]) { - const sortedInterpreters = interpreters.slice(); - // tslint:disable-next-line:no-non-null-assertion - sortedInterpreters.sort((a, b) => (a.version && b.version ? compare(a.version.raw, b.version.raw) : 0)); - if (sortedInterpreters.length > 0) { - return sortedInterpreters[sortedInterpreters.length - 1]; - } + return undefined; } private addCondaPathChangedHandler() { @@ -396,8 +406,8 @@ export class CondaService implements ICondaService { } if (this.platform.isWindows && this.registryLookupForConda) { const interpreters = await this.registryLookupForConda.getInterpreters(); - const condaInterpreters = interpreters.filter(this.detectCondaEnvironment); - const condaInterpreter = this.getLatestVersion(condaInterpreters); + const condaInterpreters = interpreters.filter(CondaService.detectCondaEnvironment); + const condaInterpreter = CondaService.getLatestVersion(condaInterpreters); if (condaInterpreter) { const interpreterPath = await this.getCondaFileFromInterpreter( condaInterpreter.path, diff --git a/src/client/testing/common/debugLauncher.ts b/src/client/testing/common/debugLauncher.ts index 64e1fb01a095..9620cacac292 100644 --- a/src/client/testing/common/debugLauncher.ts +++ b/src/client/testing/common/debugLauncher.ts @@ -32,7 +32,7 @@ export class DebugLauncher implements ITestDebugLauncher { } public async launchDebugger(options: LaunchOptions) { - if (options.token && options.token!.isCancellationRequested) { + if (options.token && options.token.isCancellationRequested) { return; } diff --git a/src/client/testing/common/managers/baseTestManager.ts b/src/client/testing/common/managers/baseTestManager.ts index 8fb8edd9e33c..1154933f10fe 100644 --- a/src/client/testing/common/managers/baseTestManager.ts +++ b/src/client/testing/common/managers/baseTestManager.ts @@ -144,7 +144,7 @@ export abstract class BaseTestManager implements ITestManager { return; } - this.testResultsService.resetResults(this.tests!); + this.testResultsService.resetResults(this.tests); } public async discoverTests( cmdSource: CommandSource, diff --git a/src/client/testing/common/services/configSettingService.ts b/src/client/testing/common/services/configSettingService.ts index 3fd888620750..1976a51c0144 100644 --- a/src/client/testing/common/services/configSettingService.ts +++ b/src/client/testing/common/services/configSettingService.ts @@ -67,7 +67,7 @@ export class TestConfigSettingsService implements ITestConfigSettingsService { throw new Error(`Test directory does not belong to any workspace (${testDirectory})`); } // tslint:disable-next-line:no-non-null-assertion - pythonConfig = this.workspaceService.getConfiguration('python', workspaceFolder!.uri); + pythonConfig = this.workspaceService.getConfiguration('python', workspaceFolder.uri); } return pythonConfig.update(setting, value); diff --git a/src/client/testing/configuration.ts b/src/client/testing/configuration.ts index 6c7adde7ede1..08e742917e3f 100644 --- a/src/client/testing/configuration.ts +++ b/src/client/testing/configuration.ts @@ -8,7 +8,7 @@ import { IConfigurationService, Product } from '../common/types'; import { IServiceContainer } from '../ioc/types'; import { sendTelemetryEvent } from '../telemetry'; import { EventName } from '../telemetry/constants'; -import { TestConfiguringTelemetry, TestTool } from '../telemetry/types'; +import { TestConfiguringTelemetry } from '../telemetry/types'; import { BufferedTestConfigSettingsService } from './common/services/configSettingService'; import { ITestsHelper, UnitTestProduct } from './common/types'; import { @@ -124,7 +124,7 @@ export class UnitTestConfigurationService implements ITestConfigurationService { return Promise.reject(null); } const helper = this.serviceContainer.get(ITestsHelper); - telemetryProps.tool = helper.parseProviderName(selectedTestRunner) as TestTool; + telemetryProps.tool = helper.parseProviderName(selectedTestRunner); const delayed = new BufferedTestConfigSettingsService(); const factory = this.serviceContainer.get( ITestConfigurationManagerFactory diff --git a/src/client/typeFormatters/contracts.ts b/src/client/typeFormatters/contracts.ts index 62bf68fd46a3..ed7ddf629819 100644 --- a/src/client/typeFormatters/contracts.ts +++ b/src/client/typeFormatters/contracts.ts @@ -1,5 +1,5 @@ export class BlockRegEx { - constructor(private regEx: RegExp, public startWord: String) {} + constructor(private regEx: RegExp, public startWord: string) {} public test(value: string): boolean { // Clear the cache this.regEx.lastIndex = -1;