Skip to content

Commit e3960a0

Browse files
authored
Merge pull request #5405 from 50Wliu/users/winstonliu/coreclr-debug-nullability
coreclr-debug nullability
2 parents 1f2d7de + 9b5d381 commit e3960a0

File tree

9 files changed

+223
-232
lines changed

9 files changed

+223
-232
lines changed

src/coreclr-debug/ParsedEnvironmentFile.ts

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import * as fs from 'fs-extra';
6+
import * as fs from 'fs';
77

88
export class ParsedEnvironmentFile {
99
public Env: { [key: string]: any };
10-
public Warning: string | null;
10+
public Warning: string | undefined;
1111

12-
private constructor(env: { [key: string]: any }, warning: string | null) {
12+
private constructor(env: { [key: string]: any }, warning: string | undefined) {
1313
this.Env = env;
1414
this.Warning = warning;
1515
}
@@ -20,26 +20,22 @@ export class ParsedEnvironmentFile {
2020
}
2121

2222
public static CreateFromContent(content: string, envFile: string, initialEnv: { [key: string]: any } | undefined): ParsedEnvironmentFile {
23-
2423
// Remove UTF-8 BOM if present
2524
if (content.charAt(0) === '\uFEFF') {
26-
content = content.substr(1);
25+
content = content.substring(1);
2726
}
2827

2928
let parseErrors: string[] = [];
30-
let env: { [key: string]: any } = initialEnv;
31-
if (!env) {
32-
env = {};
33-
}
29+
let env = initialEnv ?? {};
3430

3531
content.split("\n").forEach(line => {
3632
// Split the line between key and value
37-
const r: RegExpMatchArray = line.match(/^\s*([\w\.\-]+)\s*=\s*(.*)?\s*$/);
33+
const match = line.match(/^\s*([\w\.\-]+)\s*=\s*(.*)?\s*$/);
3834

39-
if (r !== null) {
40-
const key: string = r[1];
41-
let value: string = r[2] || "";
42-
if ((value.length > 0) && (value.charAt(0) === '"') && (value.charAt(value.length - 1) === '"')) {
35+
if (match !== null) {
36+
const key = match[1];
37+
let value = match[2] ?? "";
38+
if (value.length > 0 && value.charAt(0) === '"' && value.charAt(value.length - 1) === '"') {
4339
value = value.replace(/\\n/gm, "\n");
4440
}
4541

@@ -57,14 +53,11 @@ export class ParsedEnvironmentFile {
5753
});
5854

5955
// show error message if single lines cannot get parsed
60-
let warning: string = null;
56+
let warning: string | undefined;
6157
if (parseErrors.length !== 0) {
62-
warning = "Ignoring non-parseable lines in envFile " + envFile + ": ";
63-
parseErrors.forEach(function (value, idx, array) {
64-
warning += "\"" + value + "\"" + ((idx !== array.length - 1) ? ", " : ".");
65-
});
58+
warning = `Ignoring non-parseable lines in envFile ${envFile}: ${parseErrors.join(", ")}.`;
6659
}
6760

6861
return new ParsedEnvironmentFile(env, warning);
6962
}
70-
}
63+
}

src/coreclr-debug/activate.ts

Lines changed: 35 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,26 @@ import { DebuggerPrerequisiteWarning, DebuggerPrerequisiteFailure, DebuggerNotIn
1212
import { EventStream } from '../EventStream';
1313
import CSharpExtensionExports from '../CSharpExtensionExports';
1414
import { getRuntimeDependencyPackageWithId } from '../tools/RuntimeDependencyPackageUtils';
15-
import { getDotnetInfo, DotnetInfo } from '../utils/getDotnetInfo';
15+
import { getDotnetInfo } from '../utils/getDotnetInfo';
1616
import { DotnetDebugConfigurationProvider } from './debugConfigurationProvider';
1717
import { Options } from '../omnisharp/options';
1818

19-
let _debugUtil: CoreClrDebugUtil = null;
20-
2119
export async function activate(thisExtension: vscode.Extension<CSharpExtensionExports>, context: vscode.ExtensionContext, platformInformation: PlatformInformation, eventStream: EventStream, options: Options) {
22-
_debugUtil = new CoreClrDebugUtil(context.extensionPath);
20+
const debugUtil = new CoreClrDebugUtil(context.extensionPath);
2321

24-
if (!CoreClrDebugUtil.existsSync(_debugUtil.debugAdapterDir())) {
22+
if (!CoreClrDebugUtil.existsSync(debugUtil.debugAdapterDir())) {
2523
let isValidArchitecture: boolean = await checkIsValidArchitecture(platformInformation, eventStream);
2624
// If this is a valid architecture, we should have had a debugger, so warn if we didn't, otherwise
2725
// a warning was already issued, so do nothing.
2826
if (isValidArchitecture) {
2927
eventStream.post(new DebuggerPrerequisiteFailure("[ERROR]: C# Extension failed to install the debugger package."));
3028
showInstallErrorMessage(eventStream);
3129
}
32-
} else if (!CoreClrDebugUtil.existsSync(_debugUtil.installCompleteFilePath())) {
33-
completeDebuggerInstall(platformInformation, eventStream, options);
30+
} else if (!CoreClrDebugUtil.existsSync(debugUtil.installCompleteFilePath())) {
31+
completeDebuggerInstall(debugUtil, platformInformation, eventStream, options);
3432
}
3533

36-
const factory = new DebugAdapterExecutableFactory(platformInformation, eventStream, thisExtension.packageJSON, thisExtension.extensionPath, options);
34+
const factory = new DebugAdapterExecutableFactory(debugUtil, platformInformation, eventStream, thisExtension.packageJSON, thisExtension.extensionPath, options);
3735
context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('coreclr', new DotnetDebugConfigurationProvider(platformInformation)));
3836
context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('clr', new DotnetDebugConfigurationProvider(platformInformation)));
3937
context.subscriptions.push(vscode.debug.registerDebugAdapterDescriptorFactory('coreclr', factory));
@@ -74,30 +72,29 @@ async function checkIsValidArchitecture(platformInformation: PlatformInformation
7472
return false;
7573
}
7674

77-
async function completeDebuggerInstall(platformInformation: PlatformInformation, eventStream: EventStream, options: Options): Promise<boolean> {
78-
return _debugUtil.checkDotNetCli(options.dotNetCliPaths)
79-
.then(async (dotnetInfo: DotnetInfo) => {
75+
async function completeDebuggerInstall(debugUtil: CoreClrDebugUtil, platformInformation: PlatformInformation, eventStream: EventStream, options: Options): Promise<boolean> {
76+
try {
77+
await debugUtil.checkDotNetCli(options.dotNetCliPaths);
78+
const isValidArchitecture = await checkIsValidArchitecture(platformInformation, eventStream);
79+
if (!isValidArchitecture) {
80+
eventStream.post(new DebuggerNotInstalledFailure());
81+
vscode.window.showErrorMessage('Failed to complete the installation of the C# extension. Please see the error in the output window below.');
82+
return false;
83+
}
8084

81-
let isValidArchitecture: boolean = await checkIsValidArchitecture(platformInformation, eventStream);
85+
// Write install.complete
86+
CoreClrDebugUtil.writeEmptyFile(debugUtil.installCompleteFilePath());
8287

83-
if (!isValidArchitecture) {
84-
eventStream.post(new DebuggerNotInstalledFailure());
85-
vscode.window.showErrorMessage('Failed to complete the installation of the C# extension. Please see the error in the output window below.');
86-
return false;
87-
}
88-
89-
// Write install.complete
90-
CoreClrDebugUtil.writeEmptyFile(_debugUtil.installCompleteFilePath());
88+
return true;
89+
} catch (err) {
90+
const error = err as Error;
9191

92-
return true;
93-
}, (err) => {
94-
// Check for dotnet tools failed. pop the UI
95-
// err is a DotNetCliError but use defaults in the unexpected case that it's not
96-
showDotnetToolsWarning(err.ErrorMessage || _debugUtil.defaultDotNetCliErrorMessage());
97-
eventStream.post(new DebuggerPrerequisiteWarning(err.ErrorString || err));
98-
// TODO: log telemetry?
99-
return false;
100-
});
92+
// Check for dotnet tools failed. pop the UI
93+
showDotnetToolsWarning(error.message);
94+
eventStream.post(new DebuggerPrerequisiteWarning(error.message));
95+
// TODO: log telemetry?
96+
return false;
97+
}
10198
}
10299

103100
function showInstallErrorMessage(eventStream: EventStream) {
@@ -133,7 +130,7 @@ function showDotnetToolsWarning(message: string): void {
133130
// Else it will launch the debug adapter
134131
export class DebugAdapterExecutableFactory implements vscode.DebugAdapterDescriptorFactory {
135132

136-
constructor(private readonly platformInfo: PlatformInformation, private readonly eventStream: EventStream, private readonly packageJSON: any, private readonly extensionPath: string, private readonly options: Options) {
133+
constructor(private readonly debugUtil: CoreClrDebugUtil, private readonly platformInfo: PlatformInformation, private readonly eventStream: EventStream, private readonly packageJSON: any, private readonly extensionPath: string, private readonly options: Options) {
137134
}
138135

139136
async createDebugAdapterDescriptor(_session: vscode.DebugSession, executable: vscode.DebugAdapterExecutable | undefined): Promise<vscode.DebugAdapterDescriptor> {
@@ -161,8 +158,7 @@ export class DebugAdapterExecutableFactory implements vscode.DebugAdapterDescrip
161158
}
162159
// install.complete does not exist, check dotnetCLI to see if we can complete.
163160
else if (!CoreClrDebugUtil.existsSync(util.installCompleteFilePath())) {
164-
let success: boolean = await completeDebuggerInstall(this.platformInfo, this.eventStream, this.options);
165-
161+
let success = await completeDebuggerInstall(this.debugUtil, this.platformInfo, this.eventStream, this.options);
166162
if (!success) {
167163
this.eventStream.post(new DebuggerNotInstalledFailure());
168164
throw new Error('Failed to complete the installation of the C# extension. Please see the error in the output window below.');
@@ -172,14 +168,16 @@ export class DebugAdapterExecutableFactory implements vscode.DebugAdapterDescrip
172168

173169
// debugger has finished installation, kick off our debugger process
174170

175-
// Check for targetArchitecture
176-
let dotNetInfo = await getDotnetInfo(this.options.dotNetCliPaths);
177-
const targetArchitecture: string = getTargetArchitecture(this.platformInfo, _session.configuration.targetArchitecture, dotNetInfo);
178-
179171
// use the executable specified in the package.json if it exists or determine it based on some other information (e.g. the session)
180172
if (!executable) {
173+
const dotNetInfo = await getDotnetInfo(this.options.dotNetCliPaths);
174+
const targetArchitecture = getTargetArchitecture(this.platformInfo, _session.configuration.targetArchitecture, dotNetInfo);
181175
const command = path.join(common.getExtensionPath(), ".debugger", targetArchitecture, "vsdbg-ui" + CoreClrDebugUtil.getPlatformExeExtension());
182-
executable = new vscode.DebugAdapterExecutable(command, [], { env: { 'DOTNET_ROOT' : dotNetInfo.CliPath ? path.dirname(dotNetInfo.CliPath) : '' } });
176+
executable = new vscode.DebugAdapterExecutable(command, [], {
177+
env: {
178+
DOTNET_ROOT: dotNetInfo.CliPath ? path.dirname(dotNetInfo.CliPath) : '',
179+
}
180+
});
183181
}
184182

185183
// make VS Code launch the DA executable

src/coreclr-debug/debugConfigurationProvider.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { PlatformInformation } from '../platform';
1111
export class DotnetDebugConfigurationProvider implements vscode.DebugConfigurationProvider {
1212
constructor(public platformInformation: PlatformInformation) {}
1313

14-
public async resolveDebugConfigurationWithSubstitutedVariables(folder: vscode.WorkspaceFolder | undefined, debugConfiguration: vscode.DebugConfiguration, token?: vscode.CancellationToken): Promise<vscode.DebugConfiguration>
14+
public async resolveDebugConfigurationWithSubstitutedVariables(folder: vscode.WorkspaceFolder | undefined, debugConfiguration: vscode.DebugConfiguration, token?: vscode.CancellationToken): Promise<vscode.DebugConfiguration | null | undefined>
1515
{
1616
if (!debugConfiguration)
1717
{
@@ -21,7 +21,7 @@ export class DotnetDebugConfigurationProvider implements vscode.DebugConfigurati
2121
// Process Id is empty, handle Attach to Process Dialog.
2222
if (debugConfiguration.request === "attach" && !debugConfiguration.processId && !debugConfiguration.processName)
2323
{
24-
let process: AttachItem = undefined;
24+
let process: AttachItem | undefined;
2525
if (debugConfiguration.pipeTransport)
2626
{
2727
process = await RemoteAttachPicker.ShowAttachEntries(debugConfiguration, this.platformInformation);
@@ -33,15 +33,15 @@ export class DotnetDebugConfigurationProvider implements vscode.DebugConfigurati
3333
process = await attacher.ShowAttachEntries();
3434
}
3535

36-
if (process)
36+
if (process !== undefined)
3737
{
3838
debugConfiguration.processId = process.id;
3939

40-
if (debugConfiguration.type == "coreclr" &&
41-
this.platformInformation.isMacOS() &&
40+
if (debugConfiguration.type == "coreclr" &&
41+
this.platformInformation.isMacOS() &&
4242
this.platformInformation.architecture == 'arm64')
4343
{
44-
// For Apple Silicon M1, it is possible that the process we are attaching to is being emulated as x86_64.
44+
// For Apple Silicon M1, it is possible that the process we are attaching to is being emulated as x86_64.
4545
// The process is emulated if it has process flags has P_TRANSLATED (0x20000).
4646
if (process.flags & 0x20000)
4747
{
@@ -62,4 +62,4 @@ export class DotnetDebugConfigurationProvider implements vscode.DebugConfigurati
6262

6363
return debugConfiguration;
6464
}
65-
}
65+
}

0 commit comments

Comments
 (0)