microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
1.7.1

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/debugger/direct/directDebugSession.ts

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