microsoft/vscode-react-native

Public

mirrored from https://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
add-signproj-for-microbuild1

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/debugger/rnDebugSession.ts

304lines · modeblame

6e1bcd36RedMickey6 years ago1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
4import * as path from "path";
09f6024fHeniker4 years ago5import * as vscode from "vscode";
6e1bcd36RedMickey6 years ago6import * as mkdirp from "mkdirp";
623be8a6Ezio Li2 years ago7import { logger } from "@vscode/debugadapter";
6e1bcd36RedMickey6 years ago8import { DebugProtocol } from "vscode-debugprotocol";
09f6024fHeniker4 years ago9import * as nls from "vscode-nls";
6e1bcd36RedMickey6 years ago10import { ProjectVersionHelper } from "../common/projectVersionHelper";
11import { TelemetryHelper } from "../common/telemetryHelper";
a6562589RedMickey6 years ago12import { RnCDPMessageHandler } from "../cdp-proxy/CDPMessageHandlers/rnCDPMessageHandler";
09f6024fHeniker4 years ago13import { ErrorHelper } from "../common/error/errorHelper";
14import { InternalErrorCode } from "../common/error/internalErrorCode";
88c519c3Ezio Li2 years ago15import { ReactNativeProjectHelper } from "../common/reactNativeProjectHelper";
09f6024fHeniker4 years ago16import { MultipleLifetimesAppWorker } from "./appWorker";
34472878RedMickey5 years ago17import {
18DebugSessionBase,
19DebugSessionStatus,
20IAttachRequestArgs,
21ILaunchRequestArgs,
22} from "./debugSessionBase";
1bdccb66RedMickey6 years ago23import { JsDebugConfigAdapter } from "./jsDebugConfigAdapter";
d93677adRedMickey4 years ago24import { RNSession } from "./debugSessionWrapper";
09f6024fHeniker4 years ago25
34472878RedMickey5 years ago26nls.config({
27messageFormat: nls.MessageFormat.bundle,
28bundleFormat: nls.BundleFormat.standalone,
29})();
6e1bcd36RedMickey6 years ago30const localize = nls.loadMessageBundle();
31
2c19da7fRedMickey6 years ago32export class RNDebugSession extends DebugSessionBase {
e23d1841RedMickey6 years ago33private appWorker: MultipleLifetimesAppWorker | null;
6e491635RedMickey6 years ago34private onDidStartDebugSessionHandler: vscode.Disposable;
35private onDidTerminateDebugSessionHandler: vscode.Disposable;
6e1bcd36RedMickey6 years ago36
d93677adRedMickey4 years ago37constructor(rnSession: RNSession) {
38super(rnSession);
4c757eebRedMickey6 years ago39
40// variables definition
e23d1841RedMickey6 years ago41this.appWorker = null;
42
6e491635RedMickey6 years ago43this.onDidStartDebugSessionHandler = vscode.debug.onDidStartDebugSession(
34472878RedMickey5 years ago44this.handleStartDebugSession.bind(this),
4c757eebRedMickey6 years ago45);
46
6e491635RedMickey6 years ago47this.onDidTerminateDebugSessionHandler = vscode.debug.onDidTerminateDebugSession(
34472878RedMickey5 years ago48this.handleTerminateDebugSession.bind(this),
4c757eebRedMickey6 years ago49);
6e1bcd36RedMickey6 years ago50}
51
34472878RedMickey5 years ago52protected async launchRequest(
53response: DebugProtocol.LaunchResponse,
54launchArgs: ILaunchRequestArgs,
55// eslint-disable-next-line @typescript-eslint/no-unused-vars
56request?: DebugProtocol.Request,
57): Promise<void> {
0d77292aJiglioNero4 years ago58try {
59try {
4ccd0d65Ezio Li2 years ago60if (launchArgs.platform != "exponent") {
61await ReactNativeProjectHelper.verifyMetroConfigFile(launchArgs.cwd);
62}
0d77292aJiglioNero4 years ago63await this.initializeSettings(launchArgs);
64logger.log("Launching the application");
65logger.verbose(`Launching the application: ${JSON.stringify(launchArgs, null, 2)}`);
34472878RedMickey5 years ago66
0d77292aJiglioNero4 years ago67await this.appLauncher.launch(launchArgs);
68
69if (!launchArgs.enableDebug) {
70this.sendResponse(response);
71// if debugging is not enabled skip attach request
72return;
73}
74} catch (error) {
75throw ErrorHelper.getInternalError(
76InternalErrorCode.ApplicationLaunchFailed,
77error.message || error,
78);
79}
80// if debugging is enabled start attach request
d93677adRedMickey4 years ago81await this.vsCodeDebugSession.customRequest("attach", launchArgs);
82this.sendResponse(response);
0d77292aJiglioNero4 years ago83} catch (error) {
19df32dcRedMickey4 years ago84this.terminateWithErrorResponse(error, response);
0d77292aJiglioNero4 years ago85}
6e1bcd36RedMickey6 years ago86}
87
34472878RedMickey5 years ago88protected async attachRequest(
89response: DebugProtocol.AttachResponse,
90attachArgs: IAttachRequestArgs,
91// eslint-disable-next-line @typescript-eslint/no-unused-vars
92request?: DebugProtocol.Request,
93): Promise<void> {
6e1bcd36RedMickey6 years ago94let extProps = {
95platform: {
96value: attachArgs.platform,
97isPii: false,
98},
99};
100
101this.previousAttachArgs = attachArgs;
0d77292aJiglioNero4 years ago102
103return new Promise<void>(async (resolve, reject) => {
104try {
105await this.initializeSettings(attachArgs);
106logger.log("Attaching to the application");
107logger.verbose(
108`Attaching to the application: ${JSON.stringify(attachArgs, null, 2)}`,
109);
110
111const versions = await ProjectVersionHelper.getReactNativeVersions(
112this.projectRootPath,
113ProjectVersionHelper.generateAdditionalPackagesToCheckByPlatform(attachArgs),
114);
115extProps = TelemetryHelper.addPlatformPropertiesToTelemetryProperties(
116attachArgs,
117versions,
118extProps,
119);
120
121// eslint-disable-next-line @typescript-eslint/no-unused-vars
122await TelemetryHelper.generate("attach", extProps, async generator => {
123attachArgs.port =
124attachArgs.port || this.appLauncher.getPackagerPort(attachArgs.cwd);
125
126const cdpProxy = this.appLauncher.getRnCdpProxy();
127await cdpProxy.stopServer();
128await cdpProxy.initializeServer(
129new RnCDPMessageHandler(),
130this.cdpProxyLogLevel,
dcabd9c8RedMickey4 years ago131this.cancellationTokenSource.token,
34472878RedMickey5 years ago132);
0d77292aJiglioNero4 years ago133
bfcc8a29Samriel4 years ago134if (attachArgs.request === "attach") {
135await this.preparePackagerBeforeAttach(attachArgs, versions);
136}
0d77292aJiglioNero4 years ago137
138logger.log(
139localize("StartingDebuggerAppWorker", "Starting debugger app worker."),
34472878RedMickey5 years ago140);
0d77292aJiglioNero4 years ago141
142const sourcesStoragePath = path.join(this.projectRootPath, ".vscode", ".react");
143// Create folder if not exist to avoid problems if
144// RN project root is not a ${workspaceFolder}
145mkdirp.sync(sourcesStoragePath);
146
147// If launch is invoked first time, appWorker is undefined, so create it here
148this.appWorker = new MultipleLifetimesAppWorker(
34472878RedMickey5 years ago149attachArgs,
0d77292aJiglioNero4 years ago150sourcesStoragePath,
151this.projectRootPath,
152this.cancellationTokenSource.token,
153undefined,
34472878RedMickey5 years ago154);
0d77292aJiglioNero4 years ago155this.appLauncher.setAppWorker(this.appWorker);
156
157this.appWorker.on("connected", (port: number) => {
158if (this.cancellationTokenSource.token.isCancellationRequested) {
159return this.appWorker?.stop();
160}
161
162logger.log(
163localize(
164"DebuggerWorkerLoadedRuntimeOnPort",
165"Debugger worker loaded runtime on port {0}",
166port,
167),
168);
169
170cdpProxy.setApplicationTargetPort(port);
171
172if (this.debugSessionStatus === DebugSessionStatus.ConnectionPending) {
173return;
174}
34472878RedMickey5 years ago175
0d77292aJiglioNero4 years ago176if (this.debugSessionStatus === DebugSessionStatus.FirstConnection) {
177this.debugSessionStatus = DebugSessionStatus.FirstConnectionPending;
178this.establishDebugSession(attachArgs, resolve);
179} else if (
180this.debugSessionStatus === DebugSessionStatus.ConnectionAllowed
181) {
182if (this.nodeSession) {
183this.debugSessionStatus = DebugSessionStatus.ConnectionPending;
09f6024fHeniker4 years ago184void this.nodeSession.customRequest(this.terminateCommand);
0d77292aJiglioNero4 years ago185}
186}
34472878RedMickey5 years ago187});
0d77292aJiglioNero4 years ago188
189if (this.cancellationTokenSource.token.isCancellationRequested) {
190return this.appWorker.stop();
191}
192return await this.appWorker.start();
193});
194} catch (error) {
195reject(error);
196}
d93677adRedMickey4 years ago197})
198.then(() => {
199this.sendResponse(response);
200})
201.catch(err =>
19df32dcRedMickey4 years ago202this.terminateWithErrorResponse(
d93677adRedMickey4 years ago203ErrorHelper.getInternalError(
204InternalErrorCode.CouldNotAttachToDebugger,
205err.message || err,
206),
207response,
0d77292aJiglioNero4 years ago208),
d93677adRedMickey4 years ago209);
6e1bcd36RedMickey6 years ago210}
211
34472878RedMickey5 years ago212protected async disconnectRequest(
213response: DebugProtocol.DisconnectResponse,
214args: DebugProtocol.DisconnectArguments,
215request?: DebugProtocol.Request,
216): Promise<void> {
6e1bcd36RedMickey6 years ago217// The client is about to disconnect so first we need to stop app worker
218if (this.appWorker) {
219this.appWorker.stop();
220}
221
6e491635RedMickey6 years ago222this.onDidStartDebugSessionHandler.dispose();
223this.onDidTerminateDebugSessionHandler.dispose();
224
0d77292aJiglioNero4 years ago225return super.disconnectRequest(response, args, request);
4c757eebRedMickey6 years ago226}
227
34472878RedMickey5 years ago228protected establishDebugSession(
229attachArgs: IAttachRequestArgs,
230resolve?: (value?: void | PromiseLike<void> | undefined) => void,
231): void {
1bdccb66RedMickey6 years ago232const attachConfiguration = JsDebugConfigAdapter.createDebuggingConfigForPureRN(
233attachArgs,
234this.appLauncher.getCdpProxyPort(),
d93677adRedMickey4 years ago235this.rnSession.sessionId,
1bdccb66RedMickey6 years ago236);
a6562589RedMickey6 years ago237
34472878RedMickey5 years ago238vscode.debug
239.startDebugging(this.appLauncher.getWorkspaceFolder(), attachConfiguration, {
d93677adRedMickey4 years ago240parentSession: this.vsCodeDebugSession,
ebbd64f1RedMickey6 years ago241consoleMode: vscode.DebugConsoleMode.MergeWithParent,
34472878RedMickey5 years ago242})
243.then(
244(childDebugSessionStarted: boolean) => {
245if (childDebugSessionStarted) {
246this.debugSessionStatus = DebugSessionStatus.ConnectionDone;
247this.setConnectionAllowedIfPossible();
248if (resolve) {
249this.debugSessionStatus = DebugSessionStatus.ConnectionAllowed;
250resolve();
251}
252} else {
253this.debugSessionStatus = DebugSessionStatus.ConnectionFailed;
254this.setConnectionAllowedIfPossible();
255this.resetFirstConnectionStatus();
256throw new Error("Cannot start child debug session");
257}
258},
259err => {
260this.debugSessionStatus = DebugSessionStatus.ConnectionFailed;
261this.setConnectionAllowedIfPossible();
262this.resetFirstConnectionStatus();
263throw err;
264},
265);
4c757eebRedMickey6 years ago266}
6e1bcd36RedMickey6 years ago267
0d77292aJiglioNero4 years ago268private handleStartDebugSession(debugSession: vscode.DebugSession): void {
4c757eebRedMickey6 years ago269if (
d93677adRedMickey4 years ago270debugSession.configuration.rnDebugSessionId === this.rnSession.sessionId &&
34472878RedMickey5 years ago271debugSession.type === this.pwaNodeSessionName
4c757eebRedMickey6 years ago272) {
273this.nodeSession = debugSession;
274}
275}
276
0d77292aJiglioNero4 years ago277private handleTerminateDebugSession(debugSession: vscode.DebugSession): void {
4c757eebRedMickey6 years ago278if (
d93677adRedMickey4 years ago279debugSession.configuration.rnDebugSessionId === this.rnSession.sessionId &&
34472878RedMickey5 years ago280debugSession.type === this.pwaNodeSessionName
4c757eebRedMickey6 years ago281) {
ebbd64f1RedMickey6 years ago282if (this.debugSessionStatus === DebugSessionStatus.ConnectionPending) {
5d47053fRedMickey6 years ago283this.establishDebugSession(this.previousAttachArgs);
ebbd64f1RedMickey6 years ago284} else {
19df32dcRedMickey4 years ago285void this.terminate();
ebbd64f1RedMickey6 years ago286}
4c757eebRedMickey6 years ago287}
288}
289
290private setConnectionAllowedIfPossible(): void {
291if (
34472878RedMickey5 years ago292this.debugSessionStatus === DebugSessionStatus.ConnectionDone ||
293this.debugSessionStatus === DebugSessionStatus.ConnectionFailed
4c757eebRedMickey6 years ago294) {
295this.debugSessionStatus = DebugSessionStatus.ConnectionAllowed;
296}
297}
298
299private resetFirstConnectionStatus(): void {
300if (this.debugSessionStatus === DebugSessionStatus.FirstConnectionPending) {
301this.debugSessionStatus = DebugSessionStatus.FirstConnection;
302}
303}
6e1bcd36RedMickey6 years ago304}