microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
remove-unused-debugging-code

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/debugger/rnDebugSession.ts

339lines · 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";
e07260e2Zhen Zhen Yuan (BEYONDSOFT CONSULTING INC)6 months ago11import { InternalErrorCode } from "../common/error/internalErrorCode";
12import * as semver from "semver";
6e1bcd36RedMickey6 years ago13import { TelemetryHelper } from "../common/telemetryHelper";
a6562589RedMickey6 years ago14import { RnCDPMessageHandler } from "../cdp-proxy/CDPMessageHandlers/rnCDPMessageHandler";
09f6024fHeniker4 years ago15import { ErrorHelper } from "../common/error/errorHelper";
e07260e2Zhen Zhen Yuan (BEYONDSOFT CONSULTING INC)6 months ago16
88c519c3Ezio Li2 years ago17import { ReactNativeProjectHelper } from "../common/reactNativeProjectHelper";
09f6024fHeniker4 years ago18import { MultipleLifetimesAppWorker } from "./appWorker";
34472878RedMickey5 years ago19import {
20DebugSessionBase,
21DebugSessionStatus,
22IAttachRequestArgs,
23ILaunchRequestArgs,
24} from "./debugSessionBase";
1bdccb66RedMickey6 years ago25import { JsDebugConfigAdapter } from "./jsDebugConfigAdapter";
d93677adRedMickey4 years ago26import { RNSession } from "./debugSessionWrapper";
09f6024fHeniker4 years ago27
34472878RedMickey5 years ago28nls.config({
29messageFormat: nls.MessageFormat.bundle,
30bundleFormat: nls.BundleFormat.standalone,
31})();
6e1bcd36RedMickey6 years ago32const localize = nls.loadMessageBundle();
33
2c19da7fRedMickey6 years ago34export class RNDebugSession extends DebugSessionBase {
e23d1841RedMickey6 years ago35private appWorker: MultipleLifetimesAppWorker | null;
6e491635RedMickey6 years ago36private onDidStartDebugSessionHandler: vscode.Disposable;
37private onDidTerminateDebugSessionHandler: vscode.Disposable;
6e1bcd36RedMickey6 years ago38
d93677adRedMickey4 years ago39constructor(rnSession: RNSession) {
40super(rnSession);
4c757eebRedMickey6 years ago41
42// variables definition
e23d1841RedMickey6 years ago43this.appWorker = null;
44
6e491635RedMickey6 years ago45this.onDidStartDebugSessionHandler = vscode.debug.onDidStartDebugSession(
34472878RedMickey5 years ago46this.handleStartDebugSession.bind(this),
4c757eebRedMickey6 years ago47);
48
6e491635RedMickey6 years ago49this.onDidTerminateDebugSessionHandler = vscode.debug.onDidTerminateDebugSession(
34472878RedMickey5 years ago50this.handleTerminateDebugSession.bind(this),
4c757eebRedMickey6 years ago51);
6e1bcd36RedMickey6 years ago52}
53
34472878RedMickey5 years ago54protected async launchRequest(
55response: DebugProtocol.LaunchResponse,
56launchArgs: ILaunchRequestArgs,
57// eslint-disable-next-line @typescript-eslint/no-unused-vars
58request?: DebugProtocol.Request,
59): Promise<void> {
0d77292aJiglioNero4 years ago60try {
61try {
4ccd0d65Ezio Li2 years ago62if (launchArgs.platform != "exponent") {
63await ReactNativeProjectHelper.verifyMetroConfigFile(launchArgs.cwd);
64}
e07260e2Zhen Zhen Yuan (BEYONDSOFT CONSULTING INC)6 months ago65const requiredNodeRange =
66await ProjectVersionHelper.getReactNativeRequiredNodeRange(launchArgs.cwd);
67if (requiredNodeRange) {
68const currentNode = process.version;
69const coerced = semver.coerce(currentNode);
70if (
71!coerced ||
72!semver.satisfies(coerced, requiredNodeRange, { includePrerelease: true })
73) {
74throw ErrorHelper.getInternalError(
75InternalErrorCode.CouldNotAttachToDebugger,
76`Incompatible Node.js for React Native: detected ${currentNode}; required ${requiredNodeRange}. Install a supported Node.js or change React Native version.`,
77);
78}
79}
0d77292aJiglioNero4 years ago80await this.initializeSettings(launchArgs);
81logger.log("Launching the application");
82logger.verbose(`Launching the application: ${JSON.stringify(launchArgs, null, 2)}`);
34472878RedMickey5 years ago83
0d77292aJiglioNero4 years ago84await this.appLauncher.launch(launchArgs);
85
86if (!launchArgs.enableDebug) {
87this.sendResponse(response);
88// if debugging is not enabled skip attach request
89return;
90}
91} catch (error) {
92throw ErrorHelper.getInternalError(
93InternalErrorCode.ApplicationLaunchFailed,
176f99c8ConnorQi013 months ago94(error as Error).message || error,
0d77292aJiglioNero4 years ago95);
96}
97// if debugging is enabled start attach request
d93677adRedMickey4 years ago98await this.vsCodeDebugSession.customRequest("attach", launchArgs);
99this.sendResponse(response);
0d77292aJiglioNero4 years ago100} catch (error) {
176f99c8ConnorQi013 months ago101this.terminateWithErrorResponse(error as Error, response);
0d77292aJiglioNero4 years ago102}
6e1bcd36RedMickey6 years ago103}
104
34472878RedMickey5 years ago105protected async attachRequest(
106response: DebugProtocol.AttachResponse,
107attachArgs: IAttachRequestArgs,
108// eslint-disable-next-line @typescript-eslint/no-unused-vars
109request?: DebugProtocol.Request,
110): Promise<void> {
6e1bcd36RedMickey6 years ago111let extProps = {
112platform: {
113value: attachArgs.platform,
114isPii: false,
115},
116};
117
118this.previousAttachArgs = attachArgs;
0d77292aJiglioNero4 years ago119
120return new Promise<void>(async (resolve, reject) => {
121try {
e07260e2Zhen Zhen Yuan (BEYONDSOFT CONSULTING INC)6 months ago122const requiredNodeRange =
123await ProjectVersionHelper.getReactNativeRequiredNodeRange(attachArgs.cwd);
124if (requiredNodeRange) {
125const currentNode = process.version;
126const coerced = semver.coerce(currentNode);
127if (
128!coerced ||
129!semver.satisfies(coerced, requiredNodeRange, { includePrerelease: true })
130) {
131reject(
132ErrorHelper.getInternalError(
133InternalErrorCode.CouldNotAttachToDebugger,
134`Incompatible Node.js for React Native: detected ${currentNode}; required ${requiredNodeRange}. Install a supported Node.js or change React Native version.`,
135),
136);
137return;
138}
139}
0d77292aJiglioNero4 years ago140await this.initializeSettings(attachArgs);
141logger.log("Attaching to the application");
142logger.verbose(
143`Attaching to the application: ${JSON.stringify(attachArgs, null, 2)}`,
144);
145
146const versions = await ProjectVersionHelper.getReactNativeVersions(
147this.projectRootPath,
148ProjectVersionHelper.generateAdditionalPackagesToCheckByPlatform(attachArgs),
149);
150extProps = TelemetryHelper.addPlatformPropertiesToTelemetryProperties(
151attachArgs,
152versions,
153extProps,
154);
155
156// eslint-disable-next-line @typescript-eslint/no-unused-vars
157await TelemetryHelper.generate("attach", extProps, async generator => {
158attachArgs.port =
159attachArgs.port || this.appLauncher.getPackagerPort(attachArgs.cwd);
160
161const cdpProxy = this.appLauncher.getRnCdpProxy();
162await cdpProxy.stopServer();
163await cdpProxy.initializeServer(
164new RnCDPMessageHandler(),
165this.cdpProxyLogLevel,
dcabd9c8RedMickey4 years ago166this.cancellationTokenSource.token,
34472878RedMickey5 years ago167);
0d77292aJiglioNero4 years ago168
bfcc8a29Samriel4 years ago169if (attachArgs.request === "attach") {
170await this.preparePackagerBeforeAttach(attachArgs, versions);
171}
0d77292aJiglioNero4 years ago172
173logger.log(
174localize("StartingDebuggerAppWorker", "Starting debugger app worker."),
34472878RedMickey5 years ago175);
0d77292aJiglioNero4 years ago176
177const sourcesStoragePath = path.join(this.projectRootPath, ".vscode", ".react");
178// Create folder if not exist to avoid problems if
179// RN project root is not a ${workspaceFolder}
180mkdirp.sync(sourcesStoragePath);
181
182// If launch is invoked first time, appWorker is undefined, so create it here
183this.appWorker = new MultipleLifetimesAppWorker(
34472878RedMickey5 years ago184attachArgs,
0d77292aJiglioNero4 years ago185sourcesStoragePath,
186this.projectRootPath,
187this.cancellationTokenSource.token,
188undefined,
34472878RedMickey5 years ago189);
0d77292aJiglioNero4 years ago190this.appLauncher.setAppWorker(this.appWorker);
191
192this.appWorker.on("connected", (port: number) => {
193if (this.cancellationTokenSource.token.isCancellationRequested) {
194return this.appWorker?.stop();
195}
196
197logger.log(
198localize(
199"DebuggerWorkerLoadedRuntimeOnPort",
200"Debugger worker loaded runtime on port {0}",
201port,
202),
203);
204
205cdpProxy.setApplicationTargetPort(port);
206
207if (this.debugSessionStatus === DebugSessionStatus.ConnectionPending) {
208return;
209}
34472878RedMickey5 years ago210
0d77292aJiglioNero4 years ago211if (this.debugSessionStatus === DebugSessionStatus.FirstConnection) {
212this.debugSessionStatus = DebugSessionStatus.FirstConnectionPending;
213this.establishDebugSession(attachArgs, resolve);
214} else if (
215this.debugSessionStatus === DebugSessionStatus.ConnectionAllowed
216) {
217if (this.nodeSession) {
218this.debugSessionStatus = DebugSessionStatus.ConnectionPending;
09f6024fHeniker4 years ago219void this.nodeSession.customRequest(this.terminateCommand);
0d77292aJiglioNero4 years ago220}
221}
34472878RedMickey5 years ago222});
0d77292aJiglioNero4 years ago223
224if (this.cancellationTokenSource.token.isCancellationRequested) {
225return this.appWorker.stop();
226}
227return await this.appWorker.start();
228});
229} catch (error) {
230reject(error);
231}
d93677adRedMickey4 years ago232})
233.then(() => {
234this.sendResponse(response);
235})
236.catch(err =>
19df32dcRedMickey4 years ago237this.terminateWithErrorResponse(
d93677adRedMickey4 years ago238ErrorHelper.getInternalError(
239InternalErrorCode.CouldNotAttachToDebugger,
240err.message || err,
241),
242response,
0d77292aJiglioNero4 years ago243),
d93677adRedMickey4 years ago244);
6e1bcd36RedMickey6 years ago245}
246
34472878RedMickey5 years ago247protected async disconnectRequest(
248response: DebugProtocol.DisconnectResponse,
249args: DebugProtocol.DisconnectArguments,
250request?: DebugProtocol.Request,
251): Promise<void> {
6e1bcd36RedMickey6 years ago252// The client is about to disconnect so first we need to stop app worker
253if (this.appWorker) {
254this.appWorker.stop();
255}
256
6e491635RedMickey6 years ago257this.onDidStartDebugSessionHandler.dispose();
258this.onDidTerminateDebugSessionHandler.dispose();
259
0d77292aJiglioNero4 years ago260return super.disconnectRequest(response, args, request);
4c757eebRedMickey6 years ago261}
262
34472878RedMickey5 years ago263protected establishDebugSession(
264attachArgs: IAttachRequestArgs,
265resolve?: (value?: void | PromiseLike<void> | undefined) => void,
266): void {
1bdccb66RedMickey6 years ago267const attachConfiguration = JsDebugConfigAdapter.createDebuggingConfigForPureRN(
268attachArgs,
269this.appLauncher.getCdpProxyPort(),
d93677adRedMickey4 years ago270this.rnSession.sessionId,
1bdccb66RedMickey6 years ago271);
a6562589RedMickey6 years ago272
34472878RedMickey5 years ago273vscode.debug
274.startDebugging(this.appLauncher.getWorkspaceFolder(), attachConfiguration, {
d93677adRedMickey4 years ago275parentSession: this.vsCodeDebugSession,
ebbd64f1RedMickey6 years ago276consoleMode: vscode.DebugConsoleMode.MergeWithParent,
34472878RedMickey5 years ago277})
278.then(
279(childDebugSessionStarted: boolean) => {
280if (childDebugSessionStarted) {
281this.debugSessionStatus = DebugSessionStatus.ConnectionDone;
282this.setConnectionAllowedIfPossible();
283if (resolve) {
284this.debugSessionStatus = DebugSessionStatus.ConnectionAllowed;
285resolve();
286}
287} else {
288this.debugSessionStatus = DebugSessionStatus.ConnectionFailed;
289this.setConnectionAllowedIfPossible();
290this.resetFirstConnectionStatus();
291throw new Error("Cannot start child debug session");
292}
293},
294err => {
295this.debugSessionStatus = DebugSessionStatus.ConnectionFailed;
296this.setConnectionAllowedIfPossible();
297this.resetFirstConnectionStatus();
298throw err;
299},
300);
4c757eebRedMickey6 years ago301}
6e1bcd36RedMickey6 years ago302
0d77292aJiglioNero4 years ago303private handleStartDebugSession(debugSession: vscode.DebugSession): void {
4c757eebRedMickey6 years ago304if (
d93677adRedMickey4 years ago305debugSession.configuration.rnDebugSessionId === this.rnSession.sessionId &&
34472878RedMickey5 years ago306debugSession.type === this.pwaNodeSessionName
4c757eebRedMickey6 years ago307) {
308this.nodeSession = debugSession;
309}
310}
311
0d77292aJiglioNero4 years ago312private handleTerminateDebugSession(debugSession: vscode.DebugSession): void {
4c757eebRedMickey6 years ago313if (
d93677adRedMickey4 years ago314debugSession.configuration.rnDebugSessionId === this.rnSession.sessionId &&
34472878RedMickey5 years ago315debugSession.type === this.pwaNodeSessionName
4c757eebRedMickey6 years ago316) {
ebbd64f1RedMickey6 years ago317if (this.debugSessionStatus === DebugSessionStatus.ConnectionPending) {
5d47053fRedMickey6 years ago318this.establishDebugSession(this.previousAttachArgs);
ebbd64f1RedMickey6 years ago319} else {
19df32dcRedMickey4 years ago320void this.terminate();
ebbd64f1RedMickey6 years ago321}
4c757eebRedMickey6 years ago322}
323}
324
325private setConnectionAllowedIfPossible(): void {
326if (
34472878RedMickey5 years ago327this.debugSessionStatus === DebugSessionStatus.ConnectionDone ||
328this.debugSessionStatus === DebugSessionStatus.ConnectionFailed
4c757eebRedMickey6 years ago329) {
330this.debugSessionStatus = DebugSessionStatus.ConnectionAllowed;
331}
332}
333
334private resetFirstConnectionStatus(): void {
335if (this.debugSessionStatus === DebugSessionStatus.FirstConnectionPending) {
336this.debugSessionStatus = DebugSessionStatus.FirstConnection;
337}
338}
6e1bcd36RedMickey6 years ago339}