microsoft/vscode-react-native

Public

mirrored fromhttps://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
5940f996e19e33b2c611c0d447a7ffb66d249d80

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/debugger/direct/directDebugSession.ts

276lines · modecode

1// 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 vscode from "vscode";
5import { ProjectVersionHelper } from "../../common/projectVersionHelper";
6import { logger } from "vscode-debugadapter";
7import { TelemetryHelper } from "../../common/telemetryHelper";
8import { DebugProtocol } from "vscode-debugprotocol";
9import { HermesCDPMessageHandler } from "../../cdp-proxy/CDPMessageHandlers/hermesCDPMessageHandler";
10import { DebugSessionBase, IAttachRequestArgs, ILaunchRequestArgs } from "../debugSessionBase";
11import { JsDebugConfigAdapter } from "../jsDebugConfigAdapter";
12import { DebuggerEndpointHelper } from "../../cdp-proxy/debuggerEndpointHelper";
13import { ErrorHelper } from "../../common/error/errorHelper";
14import { InternalErrorCode } from "../../common/error/internalErrorCode";
15import * as nls from "vscode-nls";
16import { IOSDirectCDPMessageHandler } from "../../cdp-proxy/CDPMessageHandlers/iOSDirectCDPMessageHandler";
17import { PlatformType } from "../../extension/launchArgs";
18import { IWDPHelper } from "./IWDPHelper";
19
20nls.config({
21 messageFormat: nls.MessageFormat.bundle,
22 bundleFormat: nls.BundleFormat.standalone,
23})();
24const localize = nls.loadMessageBundle();
25
26export class DirectDebugSession extends DebugSessionBase {
27 private debuggerEndpointHelper: DebuggerEndpointHelper;
28 private onDidTerminateDebugSessionHandler: vscode.Disposable;
29 private iOSWKDebugProxyHelper: IWDPHelper;
30
31 constructor(session: vscode.DebugSession) {
32 super(session);
33 this.debuggerEndpointHelper = new DebuggerEndpointHelper();
34 this.iOSWKDebugProxyHelper = new IWDPHelper();
35
36 this.onDidTerminateDebugSessionHandler = vscode.debug.onDidTerminateDebugSession(
37 this.handleTerminateDebugSession.bind(this),
38 );
39 }
40
41 protected async launchRequest(
42 response: DebugProtocol.LaunchResponse,
43 launchArgs: ILaunchRequestArgs,
44 // eslint-disable-next-line @typescript-eslint/no-unused-vars
45 request?: DebugProtocol.Request,
46 ): Promise<void> {
47 let extProps = {
48 platform: {
49 value: launchArgs.platform,
50 isPii: false,
51 },
52 isDirect: {
53 value: true,
54 isPii: false,
55 },
56 };
57
58 return new Promise<void>((resolve, reject) =>
59 this.initializeSettings(launchArgs)
60 .then(() => {
61 logger.log("Launching the application");
62 logger.verbose(
63 `Launching the application: ${JSON.stringify(launchArgs, null, 2)}`,
64 );
65
66 return ProjectVersionHelper.getReactNativeVersions(
67 launchArgs.cwd,
68 ProjectVersionHelper.generateAdditionalPackagesToCheckByPlatform(
69 launchArgs,
70 ),
71 );
72 })
73 .then(versions => {
74 extProps = TelemetryHelper.addPlatformPropertiesToTelemetryProperties(
75 launchArgs,
76 versions,
77 extProps,
78 );
79
80 // eslint-disable-next-line @typescript-eslint/no-unused-vars
81 return TelemetryHelper.generate("launch", extProps, generator => {
82 return this.appLauncher.launch(launchArgs).then(() => {
83 if (launchArgs.enableDebug) {
84 launchArgs.port =
85 launchArgs.port ||
86 this.appLauncher.getPackagerPort(launchArgs.cwd);
87 this.attachRequest(response, launchArgs)
88 .then(() => {
89 resolve();
90 })
91 .catch(e => reject(e));
92 } else {
93 this.sendResponse(response);
94 resolve();
95 }
96 });
97 });
98 })
99 .catch(err => {
100 reject(
101 ErrorHelper.getInternalError(
102 InternalErrorCode.ApplicationLaunchFailed,
103 err.message || err,
104 ),
105 );
106 }),
107 ).catch(err => this.showError(err, response));
108 }
109
110 protected async attachRequest(
111 response: DebugProtocol.AttachResponse,
112 attachArgs: IAttachRequestArgs,
113 // eslint-disable-next-line @typescript-eslint/no-unused-vars
114 request?: DebugProtocol.Request,
115 ): Promise<void> {
116 let extProps = {
117 platform: {
118 value: attachArgs.platform,
119 isPii: false,
120 },
121 isDirect: {
122 value: true,
123 isPii: false,
124 },
125 };
126
127 attachArgs.webkitRangeMin = attachArgs.webkitRangeMin || 9223;
128 attachArgs.webkitRangeMax = attachArgs.webkitRangeMax || 9322;
129
130 this.previousAttachArgs = attachArgs;
131
132 return new Promise<void>((resolve, reject) =>
133 this.initializeSettings(attachArgs)
134 .then(() => {
135 logger.log("Attaching to the application");
136 logger.verbose(
137 `Attaching to the application: ${JSON.stringify(attachArgs, null, 2)}`,
138 );
139 return ProjectVersionHelper.getReactNativeVersions(
140 attachArgs.cwd,
141 ProjectVersionHelper.generateAdditionalPackagesToCheckByPlatform(
142 attachArgs,
143 ),
144 );
145 })
146 .then(versions => {
147 extProps = TelemetryHelper.addPlatformPropertiesToTelemetryProperties(
148 attachArgs,
149 versions,
150 extProps,
151 );
152
153 // eslint-disable-next-line @typescript-eslint/no-unused-vars
154 return TelemetryHelper.generate("attach", extProps, generator => {
155 attachArgs.port =
156 attachArgs.platform === PlatformType.iOS
157 ? attachArgs.port || IWDPHelper.iOS_WEBKIT_DEBUG_PROXY_DEFAULT_PORT
158 : attachArgs.port ||
159 this.appLauncher.getPackagerPort(attachArgs.cwd);
160 logger.log(`Connecting to ${attachArgs.port} port`);
161 return this.appLauncher
162 .getRnCdpProxy()
163 .stopServer()
164 .then(() =>
165 this.appLauncher
166 .getRnCdpProxy()
167 .initializeServer(
168 attachArgs.platform === PlatformType.iOS
169 ? new IOSDirectCDPMessageHandler()
170 : new HermesCDPMessageHandler(),
171 this.cdpProxyLogLevel,
172 ),
173 )
174 .then(() => {
175 if (attachArgs.platform === PlatformType.iOS) {
176 return this.iOSWKDebugProxyHelper
177 .startiOSWebkitDebugProxy(
178 attachArgs.port,
179 attachArgs.webkitRangeMin,
180 attachArgs.webkitRangeMax,
181 )
182 .then(() =>
183 this.iOSWKDebugProxyHelper.getSimulatorProxyPort(
184 attachArgs,
185 ),
186 )
187 .then(results => {
188 attachArgs.port = results.targetPort;
189 });
190 } else {
191 return Promise.resolve();
192 }
193 })
194 .then(() => this.appLauncher.getPackager().start())
195 .then(() =>
196 this.debuggerEndpointHelper.retryGetWSEndpoint(
197 `http://localhost:${attachArgs.port}`,
198 90,
199 this.cancellationTokenSource.token,
200 ),
201 )
202 .then(browserInspectUri => {
203 this.appLauncher
204 .getRnCdpProxy()
205 .setBrowserInspectUri(browserInspectUri);
206 this.establishDebugSession(attachArgs, resolve);
207 })
208 .catch(e => reject(e));
209 });
210 })
211 .catch(err => {
212 reject(
213 ErrorHelper.getInternalError(
214 InternalErrorCode.CouldNotAttachToDebugger,
215 err.message || err,
216 ),
217 );
218 }),
219 ).catch(err => this.showError(err, response));
220 }
221
222 protected async disconnectRequest(
223 response: DebugProtocol.DisconnectResponse,
224 args: DebugProtocol.DisconnectArguments,
225 request?: DebugProtocol.Request,
226 ): Promise<void> {
227 this.iOSWKDebugProxyHelper.cleanUp();
228 this.onDidTerminateDebugSessionHandler.dispose();
229 super.disconnectRequest(response, args, request);
230 }
231
232 protected establishDebugSession(
233 attachArgs: IAttachRequestArgs,
234 resolve?: (value?: void | PromiseLike<void> | undefined) => void,
235 ): void {
236 const attachConfiguration = JsDebugConfigAdapter.createDebuggingConfigForRNHermes(
237 attachArgs,
238 this.appLauncher.getCdpProxyPort(),
239 this.session.id,
240 );
241
242 vscode.debug
243 .startDebugging(this.appLauncher.getWorkspaceFolder(), attachConfiguration, {
244 parentSession: this.session,
245 consoleMode: vscode.DebugConsoleMode.MergeWithParent,
246 })
247 .then(
248 (childDebugSessionStarted: boolean) => {
249 if (childDebugSessionStarted) {
250 if (resolve) {
251 resolve();
252 }
253 } else {
254 throw new Error(
255 localize(
256 "CouldNotStartChildDebugSession",
257 "Couldn't start child debug session",
258 ),
259 );
260 }
261 },
262 err => {
263 throw err;
264 },
265 );
266 }
267
268 private handleTerminateDebugSession(debugSession: vscode.DebugSession) {
269 if (
270 debugSession.configuration.rnDebugSessionId === this.session.id &&
271 debugSession.type === this.pwaNodeSessionName
272 ) {
273 vscode.commands.executeCommand(this.stopCommand, this.session);
274 }
275 }
276}
277