microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
transitive-dependency-serialize-javascript

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/debugger/direct/directDebugSession.ts

359lines · modeblame

2c19da7fRedMickey6 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 vscode from "vscode";
623be8a6Ezio Li2 years ago5import { logger } from "@vscode/debugadapter";
2c19da7fRedMickey6 years ago6import { DebugProtocol } from "vscode-debugprotocol";
09f6024fHeniker4 years ago7import * as nls from "vscode-nls";
8import { ProjectVersionHelper } from "../../common/projectVersionHelper";
9import { TelemetryHelper } from "../../common/telemetryHelper";
259c018fYuri Skorokhodov5 years ago10import { HermesCDPMessageHandler } from "../../cdp-proxy/CDPMessageHandlers/hermesCDPMessageHandler";
19df32dcRedMickey4 years ago11import {
12DebugSessionBase,
13DebugSessionStatus,
14IAttachRequestArgs,
15ILaunchRequestArgs,
16} from "../debugSessionBase";
1bdccb66RedMickey6 years ago17import { JsDebugConfigAdapter } from "../jsDebugConfigAdapter";
984ca036RedMickey6 years ago18import { DebuggerEndpointHelper } from "../../cdp-proxy/debuggerEndpointHelper";
5514e287RedMickey6 years ago19import { ErrorHelper } from "../../common/error/errorHelper";
20import { InternalErrorCode } from "../../common/error/internalErrorCode";
259c018fYuri Skorokhodov5 years ago21import { IOSDirectCDPMessageHandler } from "../../cdp-proxy/CDPMessageHandlers/iOSDirectCDPMessageHandler";
22import { PlatformType } from "../../extension/launchArgs";
6f9a0779JiglioNero5 years ago23import { BaseCDPMessageHandler } from "../../cdp-proxy/CDPMessageHandlers/baseCDPMessageHandler";
ab0238b7RedMickey4 years ago24import { TipNotificationService } from "../../extension/services/tipsNotificationsService/tipsNotificationService";
d93677adRedMickey4 years ago25import { RNSession } from "../debugSessionWrapper";
b84470b5Ezio Li2 years ago26import { SettingsHelper } from "../../extension/settingsHelper";
529a5336Ezio Li2 years ago27import { ReactNativeProjectHelper } from "../../common/reactNativeProjectHelper";
d80f1733Ezio Li2 years ago28import { IWDPHelper } from "./IWDPHelper";
09f6024fHeniker4 years ago29
34472878RedMickey5 years ago30nls.config({
31messageFormat: nls.MessageFormat.bundle,
32bundleFormat: nls.BundleFormat.standalone,
33})();
2c19da7fRedMickey6 years ago34const localize = nls.loadMessageBundle();
35
36export class DirectDebugSession extends DebugSessionBase {
984ca036RedMickey6 years ago37private debuggerEndpointHelper: DebuggerEndpointHelper;
ebbd64f1RedMickey6 years ago38private onDidTerminateDebugSessionHandler: vscode.Disposable;
19df32dcRedMickey4 years ago39private onDidStartDebugSessionHandler: vscode.Disposable;
40private appTargetConnectionClosedHandlerDescriptor?: vscode.Disposable;
41private attachSession: vscode.DebugSession | null;
259c018fYuri Skorokhodov5 years ago42private iOSWKDebugProxyHelper: IWDPHelper;
984ca036RedMickey6 years ago43
d93677adRedMickey4 years ago44constructor(rnSession: RNSession) {
45super(rnSession);
984ca036RedMickey6 years ago46this.debuggerEndpointHelper = new DebuggerEndpointHelper();
259c018fYuri Skorokhodov5 years ago47this.iOSWKDebugProxyHelper = new IWDPHelper();
19df32dcRedMickey4 years ago48this.attachSession = null;
ebbd64f1RedMickey6 years ago49
50this.onDidTerminateDebugSessionHandler = vscode.debug.onDidTerminateDebugSession(
34472878RedMickey5 years ago51this.handleTerminateDebugSession.bind(this),
ebbd64f1RedMickey6 years ago52);
19df32dcRedMickey4 years ago53
54this.onDidStartDebugSessionHandler = vscode.debug.onDidStartDebugSession(
55this.handleStartDebugSession.bind(this),
56);
2c19da7fRedMickey6 years ago57}
58
34472878RedMickey5 years ago59protected async launchRequest(
60response: DebugProtocol.LaunchResponse,
61launchArgs: ILaunchRequestArgs,
62// eslint-disable-next-line @typescript-eslint/no-unused-vars
63request?: DebugProtocol.Request,
64): Promise<void> {
2c19da7fRedMickey6 years ago65let extProps = {
66platform: {
67value: launchArgs.platform,
68isPii: false,
69},
70isDirect: {
71value: true,
72isPii: false,
73},
74};
75
09f6024fHeniker4 years ago76void TipNotificationService.getInstance().setKnownDateForFeatureById(
f338085detatanova4 years ago77"directDebuggingWithHermes",
78);
79
0d77292aJiglioNero4 years ago80try {
81try {
4ccd0d65Ezio Li2 years ago82if (launchArgs.platform != "exponent") {
83await ReactNativeProjectHelper.verifyMetroConfigFile(launchArgs.cwd);
84}
0d77292aJiglioNero4 years ago85await this.initializeSettings(launchArgs);
86logger.log("Launching the application");
87logger.verbose(`Launching the application: ${JSON.stringify(launchArgs, null, 2)}`);
88
89const versions = await ProjectVersionHelper.getReactNativeVersions(
90this.projectRootPath,
91ProjectVersionHelper.generateAdditionalPackagesToCheckByPlatform(launchArgs),
92);
93extProps = TelemetryHelper.addPlatformPropertiesToTelemetryProperties(
94launchArgs,
95versions,
96extProps,
97);
98
99// eslint-disable-next-line @typescript-eslint/no-unused-vars
100await TelemetryHelper.generate("launch", extProps, generator =>
101this.appLauncher.launch(launchArgs),
102);
103
104if (!launchArgs.enableDebug) {
105this.sendResponse(response);
106// if debugging is not enabled skip attach request
107return;
108}
109} catch (error) {
110throw ErrorHelper.getInternalError(
111InternalErrorCode.ApplicationLaunchFailed,
112error.message || error,
113);
114}
115// if debugging is enabled start attach request
d93677adRedMickey4 years ago116await this.vsCodeDebugSession.customRequest("attach", launchArgs);
117this.sendResponse(response);
0d77292aJiglioNero4 years ago118} catch (error) {
19df32dcRedMickey4 years ago119this.terminateWithErrorResponse(error, response);
0d77292aJiglioNero4 years ago120}
2c19da7fRedMickey6 years ago121}
122
34472878RedMickey5 years ago123protected async attachRequest(
124response: DebugProtocol.AttachResponse,
125attachArgs: IAttachRequestArgs,
126// eslint-disable-next-line @typescript-eslint/no-unused-vars
127request?: DebugProtocol.Request,
128): Promise<void> {
2c19da7fRedMickey6 years ago129let extProps = {
130platform: {
131value: attachArgs.platform,
132isPii: false,
133},
134isDirect: {
135value: true,
136isPii: false,
137},
138};
139
259c018fYuri Skorokhodov5 years ago140attachArgs.webkitRangeMin = attachArgs.webkitRangeMin || 9223;
141attachArgs.webkitRangeMax = attachArgs.webkitRangeMax || 9322;
142
2c19da7fRedMickey6 years ago143this.previousAttachArgs = attachArgs;
144
0d77292aJiglioNero4 years ago145try {
146await this.initializeSettings(attachArgs);
accd6598Heniker4 years ago147
148const packager = this.appLauncher.getPackager();
149const args: Parameters<typeof packager.forMessage> = [
150// message indicates that another debugger has connected
151"Already connected:",
152{
153type: "client_log",
154level: "warn",
155mode: "BRIDGE",
156},
157];
158
159void packager.forMessage(...args).then(
160() => {
161this.showError(
162ErrorHelper.getInternalError(
163InternalErrorCode.AnotherDebuggerConnectedToPackager,
164),
165);
19df32dcRedMickey4 years ago166void this.terminate();
accd6598Heniker4 years ago167},
168() => {},
169);
170
0d77292aJiglioNero4 years ago171logger.log("Attaching to the application");
172logger.verbose(`Attaching to the application: ${JSON.stringify(attachArgs, null, 2)}`);
173
174const versions = await ProjectVersionHelper.getReactNativeVersions(
175this.projectRootPath,
176ProjectVersionHelper.generateAdditionalPackagesToCheckByPlatform(attachArgs),
177);
df1cd012lexie0111 years ago178
0d77292aJiglioNero4 years ago179extProps = TelemetryHelper.addPlatformPropertiesToTelemetryProperties(
180attachArgs,
181versions,
182extProps,
183);
184
185// eslint-disable-next-line @typescript-eslint/no-unused-vars
186await TelemetryHelper.generate("attach", extProps, async generator => {
187const port = attachArgs.useHermesEngine
188? attachArgs.port || this.appLauncher.getPackagerPort(attachArgs.cwd)
189: attachArgs.platform === PlatformType.iOS
190? attachArgs.port || IWDPHelper.iOS_WEBKIT_DEBUG_PROXY_DEFAULT_PORT
191: null;
192if (port === null) {
193throw ErrorHelper.getInternalError(
194InternalErrorCode.CouldNotDirectDebugWithoutHermesEngine,
195attachArgs.platform,
34472878RedMickey5 years ago196);
0d77292aJiglioNero4 years ago197}
198attachArgs.port = port;
199logger.log(`Connecting to ${attachArgs.port} port`);
200await this.appLauncher.getRnCdpProxy().stopServer();
201
48ca0c62RedMickey4 years ago202const cdpMessageHandler: BaseCDPMessageHandler | null = attachArgs.useHermesEngine
0d77292aJiglioNero4 years ago203? new HermesCDPMessageHandler()
204: attachArgs.platform === PlatformType.iOS
205? new IOSDirectCDPMessageHandler()
206: null;
207
48ca0c62RedMickey4 years ago208if (!cdpMessageHandler) {
0d77292aJiglioNero4 years ago209throw ErrorHelper.getInternalError(
210InternalErrorCode.CouldNotDirectDebugWithoutHermesEngine,
211attachArgs.platform,
34472878RedMickey5 years ago212);
0d77292aJiglioNero4 years ago213}
214await this.appLauncher
215.getRnCdpProxy()
dcabd9c8RedMickey4 years ago216.initializeServer(
48ca0c62RedMickey4 years ago217cdpMessageHandler,
dcabd9c8RedMickey4 years ago218this.cdpProxyLogLevel,
219this.cancellationTokenSource.token,
220);
0d77292aJiglioNero4 years ago221
222if (!attachArgs.useHermesEngine && attachArgs.platform === PlatformType.iOS) {
223await this.iOSWKDebugProxyHelper.startiOSWebkitDebugProxy(
224attachArgs.port,
225attachArgs.webkitRangeMin,
226attachArgs.webkitRangeMax,
34472878RedMickey5 years ago227);
0d77292aJiglioNero4 years ago228const results = await this.iOSWKDebugProxyHelper.getSimulatorProxyPort(
229attachArgs,
34472878RedMickey5 years ago230);
0d77292aJiglioNero4 years ago231attachArgs.port = results.targetPort;
232}
233
bfcc8a29Samriel4 years ago234if (attachArgs.request === "attach") {
235await this.preparePackagerBeforeAttach(attachArgs, versions);
236}
0d77292aJiglioNero4 years ago237
19df32dcRedMickey4 years ago238this.appTargetConnectionClosedHandlerDescriptor = this.appLauncher
239.getRnCdpProxy()
240.onApplicationTargetConnectionClosed(() => {
241if (this.attachSession) {
242if (
243this.debugSessionStatus !== DebugSessionStatus.Stopping &&
244this.debugSessionStatus !== DebugSessionStatus.Stopped
245) {
246void this.terminate();
247}
248this.appTargetConnectionClosedHandlerDescriptor?.dispose();
249}
250});
251
b84470b5Ezio Li2 years ago252const settingsPorts = SettingsHelper.getPackagerPort(attachArgs.cwd);
0d77292aJiglioNero4 years ago253const browserInspectUri = await this.debuggerEndpointHelper.retryGetWSEndpoint(
254`http://localhost:${attachArgs.port}`,
25590,
256this.cancellationTokenSource.token,
48ca0c62RedMickey4 years ago257attachArgs.useHermesEngine,
b84470b5Ezio Li2 years ago258settingsPorts,
0d77292aJiglioNero4 years ago259);
b8922151Ezio Li1 years ago260
261// Make sure expo app is using correct ws endpoint url
262const debuggerType = await this.debuggerEndpointHelper.getDebuggerTpye(
263`http://localhost:${attachArgs.port}`,
264);
265if (debuggerType == "expo") {
266const expoBrowserInspectUri = `${browserInspectUri.split("&")[0]}&page=2`;
267this.appLauncher.getRnCdpProxy().setBrowserInspectUri(expoBrowserInspectUri);
268} else {
269this.appLauncher.getRnCdpProxy().setBrowserInspectUri(browserInspectUri);
270}
271
0d77292aJiglioNero4 years ago272await this.establishDebugSession(attachArgs);
273});
d93677adRedMickey4 years ago274this.sendResponse(response);
0d77292aJiglioNero4 years ago275} catch (error) {
19df32dcRedMickey4 years ago276this.terminateWithErrorResponse(
0d77292aJiglioNero4 years ago277ErrorHelper.getInternalError(
278InternalErrorCode.CouldNotAttachToDebugger,
279error.message || error,
280),
281response,
282);
283}
2c19da7fRedMickey6 years ago284}
285
34472878RedMickey5 years ago286protected async disconnectRequest(
287response: DebugProtocol.DisconnectResponse,
288args: DebugProtocol.DisconnectArguments,
289request?: DebugProtocol.Request,
290): Promise<void> {
19df32dcRedMickey4 years ago291this.debugSessionStatus = DebugSessionStatus.Stopping;
292
0ab7b0a0Ezio Li1 years ago293// Stop packager when using expo-cli, to avoid launch conflicts in the next launch request
294if (this.appLauncher.getPackager().getPlatform() == "exponent") {
295await this.appLauncher.getPackager().stop();
296}
297
259c018fYuri Skorokhodov5 years ago298this.iOSWKDebugProxyHelper.cleanUp();
ebbd64f1RedMickey6 years ago299this.onDidTerminateDebugSessionHandler.dispose();
19df32dcRedMickey4 years ago300this.onDidStartDebugSessionHandler.dispose();
accd6598Heniker4 years ago301this.appLauncher.getPackager().closeWsConnection();
19df32dcRedMickey4 years ago302this.appTargetConnectionClosedHandlerDescriptor?.dispose();
d93677adRedMickey4 years ago303return super.disconnectRequest(response, args, request);
2c19da7fRedMickey6 years ago304}
305
0d77292aJiglioNero4 years ago306protected async establishDebugSession(attachArgs: IAttachRequestArgs): Promise<void> {
43fe950dlexie0111 years ago307const attachConfiguration = await JsDebugConfigAdapter.createDebuggingConfigForRNHermes(
1bdccb66RedMickey6 years ago308attachArgs,
309this.appLauncher.getCdpProxyPort(),
d93677adRedMickey4 years ago310this.rnSession.sessionId,
1bdccb66RedMickey6 years ago311);
b7451aefRedMickey6 years ago312
0d77292aJiglioNero4 years ago313const childDebugSessionStarted = await vscode.debug.startDebugging(
314this.appLauncher.getWorkspaceFolder(),
315attachConfiguration,
316{
d93677adRedMickey4 years ago317parentSession: this.vsCodeDebugSession,
ebbd64f1RedMickey6 years ago318consoleMode: vscode.DebugConsoleMode.MergeWithParent,
0d77292aJiglioNero4 years ago319},
320);
321if (!childDebugSessionStarted) {
322throw new Error(
323localize("CouldNotStartChildDebugSession", "Couldn't start child debug session"),
34472878RedMickey5 years ago324);
0d77292aJiglioNero4 years ago325}
b7451aefRedMickey6 years ago326}
ebbd64f1RedMickey6 years ago327
0d77292aJiglioNero4 years ago328private handleTerminateDebugSession(debugSession: vscode.DebugSession): void {
ebbd64f1RedMickey6 years ago329if (
d93677adRedMickey4 years ago330debugSession.configuration.rnDebugSessionId === this.rnSession.sessionId &&
34472878RedMickey5 years ago331debugSession.type === this.pwaNodeSessionName
ebbd64f1RedMickey6 years ago332) {
19df32dcRedMickey4 years ago333void this.terminate();
334}
335}
336
337private handleStartDebugSession(debugSession: vscode.DebugSession): void {
338if (
339this.nodeSession &&
340(debugSession as any).parentSession &&
341this.nodeSession.id === (debugSession as any).parentSession.id
342) {
343this.attachSession = debugSession;
344}
345if (
346debugSession.configuration.rnDebugSessionId === this.rnSession.sessionId &&
347debugSession.type === this.pwaNodeSessionName
348) {
349this.nodeSession = debugSession;
ebbd64f1RedMickey6 years ago350}
351}
6f9a0779JiglioNero5 years ago352
353protected async initializeSettings(args: any): Promise<any> {
354await super.initializeSettings(args);
355if (args.useHermesEngine === undefined) {
356args.useHermesEngine = true;
357}
358}
2c19da7fRedMickey6 years ago359}