diff --git a/src/configurationProvider.ts b/src/configurationProvider.ts index 69b9f0f1..9505bfb4 100644 --- a/src/configurationProvider.ts +++ b/src/configurationProvider.ts @@ -73,7 +73,7 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration try { // See https://github.com/microsoft/vscode-java-debug/issues/778 // Merge the platform specific properties to the global config to simplify the subsequent resolving logic. - this.mergePlatformProperties(folder, config); + this.mergePlatformProperties(config, folder); return this.resolveAndValidateDebugConfiguration(folder, config); } catch (ex) { utility.showErrorMessage({ @@ -110,7 +110,7 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration const launchConfigs = mainClasses.map((item) => { return { ...defaultLaunchConfig, - name: this.constructLaunchConfigName(item.mainClass, item.projectName, cache), + name: this.constructLaunchConfigName(item.mainClass, cache, item.projectName), mainClass: item.mainClass, projectName: item.projectName, }; @@ -127,7 +127,7 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration }); } - private mergePlatformProperties(_folder: vscode.WorkspaceFolder, config: vscode.DebugConfiguration) { + private mergePlatformProperties(config: vscode.DebugConfiguration, _folder?: vscode.WorkspaceFolder) { if (config && platformName && config[platformName]) { try { for (const key of Object.keys(config[platformName])) { @@ -140,7 +140,7 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration } } - private constructLaunchConfigName(mainClass: string, projectName: string, cache: {[key: string]: any}) { + private constructLaunchConfigName(mainClass: string, cache: {[key: string]: any}, projectName?: string) { const prefix = "Debug (Launch)-"; let name = prefix + mainClass.substr(mainClass.lastIndexOf(".") + 1); if (projectName !== undefined) { @@ -333,7 +333,8 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration return Object.keys(config).filter((key: string) => key !== "noDebug").length === 0; } - private async resolveLaunchConfig(folder: vscode.Uri | undefined, config: vscode.DebugConfiguration): Promise { + private async resolveLaunchConfig(folder: vscode.Uri | undefined, + config: vscode.DebugConfiguration): Promise { if (!config.mainClass || this.isFile(config.mainClass)) { const currentFile = config.mainClass || _.get(vscode.window.activeTextEditor, "document.uri.fsPath"); if (currentFile) { @@ -350,7 +351,7 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration } const containsExternalClasspaths = !_.isEmpty(config.classPaths) || !_.isEmpty(config.modulePaths); - const validationResponse = await lsPlugin.validateLaunchConfig(folder, config.mainClass, config.projectName, containsExternalClasspaths); + const validationResponse = await lsPlugin.validateLaunchConfig(config.mainClass, config.projectName, containsExternalClasspaths, folder); if (!validationResponse.mainClass.isValid || !validationResponse.projectName.isValid) { return this.fixMainClass(folder, config, validationResponse); } @@ -391,7 +392,7 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration const selectedFix = await mainClassPicker.showQuickPick(validationResponse.proposals, "Please select main class.", false); if (selectedFix) { - sendInfo(null, { + sendInfo("", { fix: "yes", fixMessage: errors.join(os.EOL), }); diff --git a/src/debugCodeLensProvider.ts b/src/debugCodeLensProvider.ts index 66f1e9bc..6821fe09 100644 --- a/src/debugCodeLensProvider.ts +++ b/src/debugCodeLensProvider.ts @@ -134,11 +134,11 @@ function debugJavaProgram(mainClass: string, projectName: string, uri: vscode.Ur return startDebugging(mainClass, projectName, uri, false); } -async function constructDebugConfig(mainClass: string, projectName: string, workspace: vscode.Uri): Promise { +async function constructDebugConfig(mainClass: string, projectName: string, workspace?: vscode.Uri): Promise { const launchConfigurations: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("launch", workspace); const rawConfigs: vscode.DebugConfiguration[] = launchConfigurations.configurations; - let debugConfig: vscode.DebugConfiguration = _.find(rawConfigs, (config) => { + let debugConfig: vscode.DebugConfiguration | undefined = _.find(rawConfigs, (config) => { return config.mainClass === mainClass && _.toString(config.projectName) === _.toString(projectName); }); @@ -174,7 +174,7 @@ async function constructDebugConfig(mainClass: string, projectName: string, work return _.cloneDeep(debugConfig); } -async function launchJsonExists(workspace: vscode.Uri): Promise { +async function launchJsonExists(workspace?: vscode.Uri): Promise { if (!workspace) { return false; } @@ -185,8 +185,8 @@ async function launchJsonExists(workspace: vscode.Uri): Promise { } export async function startDebugging(mainClass: string, projectName: string, uri: vscode.Uri, noDebug: boolean): Promise { - const workspaceFolder: vscode.WorkspaceFolder = vscode.workspace.getWorkspaceFolder(uri); - const workspaceUri: vscode.Uri = workspaceFolder ? workspaceFolder.uri : undefined; + const workspaceFolder: vscode.WorkspaceFolder | undefined = vscode.workspace.getWorkspaceFolder(uri); + const workspaceUri: vscode.Uri | undefined = workspaceFolder ? workspaceFolder.uri : undefined; const onClasspath = await isOnClasspath(uri.toString()); if (workspaceUri && onClasspath === false && !(await addToClasspath(uri))) { return false; diff --git a/src/extension.ts b/src/extension.ts index de522f2f..eab2847e 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -165,7 +165,7 @@ function specifyProgramArguments(context: vscode.ExtensionContext): Thenable { + const existConfig: vscode.DebugConfiguration | undefined = _.find(existingConfigs, (config) => { return config.mainClass === mainClass && _.toString(config.projectName) === _.toString(projectName); }); const debugConfig = existConfig || { diff --git a/src/javaDebugAdapterDescriptorFactory.ts b/src/javaDebugAdapterDescriptorFactory.ts index b82e77b3..0fd731f8 100644 --- a/src/javaDebugAdapterDescriptorFactory.ts +++ b/src/javaDebugAdapterDescriptorFactory.ts @@ -8,8 +8,9 @@ import { Type } from "./logger"; import { convertErrorToMessage, showErrorMessageWithTroubleshooting } from "./utility"; export class JavaDebugAdapterDescriptorFactory implements DebugAdapterDescriptorFactory { - public async createDebugAdapterDescriptor(_session: DebugSession, _executable: DebugAdapterExecutable): Promise { - let error: Error; + public async createDebugAdapterDescriptor(_session: DebugSession, + _executable: DebugAdapterExecutable): Promise { + let error: Error| undefined; try { const debugServerPort = (await startDebugSession()); if (debugServerPort) { diff --git a/src/languageServerPlugin.ts b/src/languageServerPlugin.ts index 8bedfe5b..1c7cd59b 100644 --- a/src/languageServerPlugin.ts +++ b/src/languageServerPlugin.ts @@ -49,14 +49,14 @@ export function resolveClasspath(mainClass: string, projectName: string) { return commands.executeJavaLanguageServerCommand(commands.JAVA_RESOLVE_CLASSPATH, mainClass, projectName); } -export function resolveMainClass(workspaceUri: vscode.Uri): Promise { +export function resolveMainClass(workspaceUri?: vscode.Uri): Promise { if (workspaceUri) { return >commands.executeJavaLanguageServerCommand(commands.JAVA_RESOLVE_MAINCLASS, workspaceUri.toString()); } return >commands.executeJavaLanguageServerCommand(commands.JAVA_RESOLVE_MAINCLASS); } -export function validateLaunchConfig(workspaceUri: vscode.Uri, mainClass: string, projectName: string, containsExternalClasspaths: boolean): +export function validateLaunchConfig(mainClass: string, projectName: string, containsExternalClasspaths: boolean, workspaceUri?: vscode.Uri): Promise { return >commands.executeJavaLanguageServerCommand(commands.JAVA_VALIDATE_LAUNCHCONFIG, workspaceUri ? workspaceUri.toString() : undefined, mainClass, projectName, containsExternalClasspaths); diff --git a/src/logger.ts b/src/logger.ts index c145da04..470a96a1 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -16,7 +16,7 @@ const SENSITIVE_PROPS = ["message", "stacktrace", "detailmessage"]; // Deprecate class Logger implements vscode.Disposable { - private reporter: TelemetryReporter = null; + private reporter: TelemetryReporter | null = null; public initialize(context: vscode.ExtensionContext, firstParty?: boolean): void { if (this.reporter) { diff --git a/src/mainClassPicker.ts b/src/mainClassPicker.ts index 4d66c5de..caee665d 100644 --- a/src/mainClassPicker.ts +++ b/src/mainClassPicker.ts @@ -88,16 +88,19 @@ class MainClassPicker { return this.getMRUTimestamp(b) - this.getMRUTimestamp(a); }); - const mostRecentlyUsedOption: IMainClassOption = (options.length && this.contains(options[0])) ? options[0] : undefined; + const mostRecentlyUsedOption: IMainClassOption | undefined = (options.length && this.contains(options[0])) ? options[0] : undefined; const isMostRecentlyUsed = (option: IMainClassOption): boolean => { - return mostRecentlyUsedOption + return !!mostRecentlyUsedOption && mostRecentlyUsedOption.mainClass === option.mainClass && mostRecentlyUsedOption.projectName === option.projectName; }; const isFromActiveEditor = (option: IMainClassOption): boolean => { - const activeEditor: TextEditor = window.activeTextEditor; + const activeEditor: TextEditor | undefined = window.activeTextEditor; const currentActiveFile: string = _.get(activeEditor, "document.uri.fsPath"); - return option.filePath && currentActiveFile && path.relative(option.filePath, currentActiveFile) === ""; + if (option.filePath && currentActiveFile) { + return path.relative(option.filePath, currentActiveFile) === ""; + } + return false; }; const isPrivileged = (option: IMainClassOption): boolean => { return isMostRecentlyUsed(option) || isFromActiveEditor(option); @@ -124,7 +127,7 @@ class MainClassPicker { adjustedDetail.push("$(clock) recently used"); } - if (isFromActiveEditor(option)) { + if (isFromActiveEditor(option) && option.filePath) { adjustedDetail.push(`$(file-text) active editor (${path.basename(option.filePath)})`); } diff --git a/src/processPicker.ts b/src/processPicker.ts index 8dc5a2bd..a9f11ff0 100644 --- a/src/processPicker.ts +++ b/src/processPicker.ts @@ -46,7 +46,7 @@ function convertToJavaProcess(pid: number, command: string, args: string): IJava return undefined; } -export async function pickJavaProcess(): Promise { +export async function pickJavaProcess(): Promise { const javaProcesses: IJavaProcess[] = []; try { await getProcesses((pid: number, _ppid: number, command: string, args: string, _date: number) => { diff --git a/src/terminalLinkProvider.ts b/src/terminalLinkProvider.ts index 6d5db9d1..d50927bb 100644 --- a/src/terminalLinkProvider.ts +++ b/src/terminalLinkProvider.ts @@ -20,7 +20,7 @@ export class JavaTerminalLinkProvder implements TerminalLinkProvider]+)\\(([\\w-$]+\\.java:\\d+)\\)"); - const result: RegExpExecArray = regex.exec(context.line); + const result: RegExpExecArray | null = regex.exec(context.line); if (result && result.length) { const stackTrace = `${result[2] || ""}${result[3]}(${result[5]})`; const sourceLineNumber = Number(result[5].split(":")[1]); diff --git a/src/threadOperations.ts b/src/threadOperations.ts index 4c3f3ecc..23ca45c6 100644 --- a/src/threadOperations.ts +++ b/src/threadOperations.ts @@ -23,7 +23,7 @@ export function initializeThreadOperations(context: vscode.ExtensionContext) { } async function operateThread(request: string, threadId: any): Promise { - const debugSession: vscode.DebugSession = vscode.debug.activeDebugSession; + const debugSession: vscode.DebugSession | undefined = vscode.debug.activeDebugSession; if (!debugSession) { return; } diff --git a/src/utility.ts b/src/utility.ts index c2e12d53..6746c57a 100644 --- a/src/utility.ts +++ b/src/utility.ts @@ -55,11 +55,11 @@ function logMessage(message: ILoggingMessage): void { } sendError(error); } else { - sendInfo(null, { message: message.message }); + sendInfo("", { message: message.message }); } // Deprecated - logger.log(message.type, { message: message.message, stack: message.stack }); + logger.log(message.type, { message: message.message, stack: message.stack || "" }); } export async function showInformationMessage(message: ILoggingMessage, ...items: string[]): Promise { @@ -79,20 +79,20 @@ export async function showErrorMessage(message: ILoggingMessage, ...items: strin export async function showInformationMessageWithTroubleshooting(message: ITroubleshootingMessage, ...items: string[]): Promise { const choice = await showInformationMessage(message, ...items, LEARN_MORE); - return handleTroubleshooting(choice, message.message, message.anchor); + return handleTroubleshooting(message.message, choice, message.anchor); } export async function showWarningMessageWithTroubleshooting(message: ITroubleshootingMessage, ...items: string[]): Promise { const choice = await showWarningMessage(message, ...items, LEARN_MORE); - return handleTroubleshooting(choice, message.message, message.anchor); + return handleTroubleshooting(message.message, choice, message.anchor); } export async function showErrorMessageWithTroubleshooting(message: ITroubleshootingMessage, ...items: string[]): Promise { const choice = await showErrorMessage(message, ...items, LEARN_MORE); - return handleTroubleshooting(choice, message.message, message.anchor); + return handleTroubleshooting(message.message, choice, message.anchor); } -function handleTroubleshooting(choice: string, message: string, anchor: string): string | undefined { +function handleTroubleshooting(message: string, choice?: string, anchor?: string): string | undefined { if (choice === LEARN_MORE) { openTroubleshootingPage(message, anchor); return undefined; @@ -101,9 +101,9 @@ function handleTroubleshooting(choice: string, message: string, anchor: string): return choice; } -export function openTroubleshootingPage(message: string, anchor: string) { +export function openTroubleshootingPage(message: string, anchor?: string) { vscode.commands.executeCommand("vscode.open", vscode.Uri.parse(anchor ? `${TROUBLESHOOTING_LINK}#${anchor}` : TROUBLESHOOTING_LINK)); - sendInfo(null, { + sendInfo("", { troubleshooting: "yes", troubleshootingMessage: message, }); @@ -183,7 +183,7 @@ export function getJavaExtensionAPI(): Thenable { return extension.activate(); } -export function getJavaExtension(): vscode.Extension { +export function getJavaExtension(): vscode.Extension | undefined { return vscode.extensions.getExtension(JAVA_EXTENSION_ID); } @@ -194,11 +194,11 @@ export function isJavaExtEnabled(): boolean { export function isJavaExtActivated(): boolean { const javaExt = vscode.extensions.getExtension(JAVA_EXTENSION_ID); - return javaExt && javaExt.isActive; + return !!javaExt && javaExt.isActive; } export function getLauncherScriptPath() { - const ext = vscode.extensions.getExtension(DEBUGGER_EXTENSION_ID); + const ext = vscode.extensions.getExtension(DEBUGGER_EXTENSION_ID)!; return path.join(ext.extensionPath, "scripts", "launcher.bat"); } diff --git a/test/extension.test.ts b/test/extension.test.ts index e342097b..a2127763 100644 --- a/test/extension.test.ts +++ b/test/extension.test.ts @@ -12,7 +12,7 @@ suite("Extension Tests", () => { test("should activate", function() { this.timeout(1 * 60 * 1000); - return vscode.extensions.getExtension("vscjava.vscode-java-debug").activate().then((_api) => { + return vscode.extensions.getExtension("vscjava.vscode-java-debug")!.activate().then((_api) => { assert.ok(true); }); }); diff --git a/tsconfig.json b/tsconfig.json index 1f32c464..5e963013 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,6 +13,7 @@ "noImplicitAny": true, "noImplicitReturns": true, "noUnusedParameters": true, + "strictNullChecks": true, "alwaysStrict": true }, "exclude": [