microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
ffdf159274093d12e32a09aafae6d0de3099bb4a

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/debuggingConfiguration/reactNativeDebugConfigProvider.ts

383lines · 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 { TelemetryHelper } from "../../common/telemetryHelper";
6import { Telemetry } from "../../common/telemetry";
7import { PlatformType } from "../launchArgs";
8import { IWDPHelper } from "../../debugger/direct/IWDPHelper";
9import { DebugScenarioNameGenerator } from "./debugScenarioNameGenerator";
10import { ILaunchRequestArgs } from "../../debugger/debugSessionBase";
11import {
12 DEBUG_TYPES,
13 DebugScenarioType,
14 DebugConfigurationQuickPickItem,
15 DebugConfigurationState,
16} from "./debugConfigTypesAndConstants";
17import { MultiStepInput, IMultiStepInput, InputStep, IQuickPickParameters } from "./multiStepInput";
18import { ConfigProviderFactory } from "./configurationProviders/configProviderFactory";
19import * as nls from "vscode-nls";
20nls.config({
21 messageFormat: nls.MessageFormat.bundle,
22 bundleFormat: nls.BundleFormat.standalone,
23})();
24const localize = nls.loadMessageBundle();
25
26export class ReactNativeDebugConfigProvider implements vscode.DebugConfigurationProvider {
27 private debugConfigurations = {
28 "Attach to Hermes application - Experimental": {
29 name: "Attach to Hermes application - Experimental",
30 cwd: "${workspaceFolder}",
31 type: DEBUG_TYPES.REACT_NATIVE_DIRECT,
32 request: "attach",
33 },
34 "Attach to Direct iOS - Experimental": {
35 name: "Attach to Direct iOS - Experimental",
36 cwd: "${workspaceFolder}",
37 type: DEBUG_TYPES.REACT_NATIVE_DIRECT,
38 request: "attach",
39 platform: PlatformType.iOS,
40 useHermesEngine: false,
41 port: IWDPHelper.iOS_WEBKIT_DEBUG_PROXY_DEFAULT_PORT, // 9221
42 },
43 "Attach to packager": {
44 name: "Attach to packager",
45 cwd: "${workspaceFolder}",
46 type: DEBUG_TYPES.REACT_NATIVE,
47 request: "attach",
48 },
49 "Debug Android": {
50 name: "Debug Android",
51 cwd: "${workspaceFolder}",
52 type: DEBUG_TYPES.REACT_NATIVE,
53 request: "launch",
54 platform: PlatformType.Android,
55 },
56 "Debug iOS": {
57 name: "Debug iOS",
58 cwd: "${workspaceFolder}",
59 type: DEBUG_TYPES.REACT_NATIVE,
60 request: "launch",
61 platform: PlatformType.iOS,
62 },
63 "Debug Windows": {
64 name: "Debug Windows",
65 cwd: "${workspaceFolder}",
66 type: DEBUG_TYPES.REACT_NATIVE,
67 request: "launch",
68 platform: PlatformType.Windows,
69 },
70 "Debug macOS": {
71 name: "Debug macOS",
72 cwd: "${workspaceFolder}",
73 type: DEBUG_TYPES.REACT_NATIVE,
74 request: "launch",
75 platform: PlatformType.macOS,
76 },
77 "Debug in Exponent": {
78 name: "Debug in Exponent",
79 cwd: "${workspaceFolder}",
80 type: DEBUG_TYPES.REACT_NATIVE,
81 request: "launch",
82 platform: PlatformType.Exponent,
83 },
84 "Debug Android Hermes - Experimental": {
85 name: "Debug Android Hermes - Experimental",
86 cwd: "${workspaceFolder}",
87 type: DEBUG_TYPES.REACT_NATIVE_DIRECT,
88 request: "launch",
89 platform: PlatformType.Android,
90 },
91 "Debug Direct iOS - Experimental": {
92 name: "Debug Direct iOS - Experimental",
93 cwd: "${workspaceFolder}",
94 type: DEBUG_TYPES.REACT_NATIVE_DIRECT,
95 request: "launch",
96 platform: PlatformType.iOS,
97 useHermesEngine: false,
98 target: "device",
99 port: IWDPHelper.iOS_WEBKIT_DEBUG_PROXY_DEFAULT_PORT, // 9221
100 },
101 "Debug iOS Hermes - Experimental": {
102 name: "Debug iOS Hermes - Experimental",
103 cwd: "${workspaceFolder}",
104 type: DEBUG_TYPES.REACT_NATIVE_DIRECT,
105 request: "launch",
106 platform: PlatformType.iOS,
107 },
108 "Debug macOS Hermes - Experimental": {
109 name: "Debug macOS Hermes - Experimental",
110 cwd: "${workspaceFolder}",
111 type: DEBUG_TYPES.REACT_NATIVE_DIRECT,
112 request: "launch",
113 platform: PlatformType.macOS,
114 },
115 "Run Android": {
116 name: "Run Android",
117 cwd: "${workspaceFolder}",
118 type: DEBUG_TYPES.REACT_NATIVE,
119 request: "launch",
120 platform: PlatformType.Android,
121 enableDebug: false,
122 },
123 "Run iOS": {
124 name: "Run iOS",
125 cwd: "${workspaceFolder}",
126 type: DEBUG_TYPES.REACT_NATIVE,
127 request: "launch",
128 platform: PlatformType.iOS,
129 enableDebug: false,
130 },
131 "Run Android Hermes - Experimental": {
132 name: "Run Android Hermes - Experimental",
133 cwd: "${workspaceFolder}",
134 type: DEBUG_TYPES.REACT_NATIVE_DIRECT,
135 request: "launch",
136 platform: PlatformType.Android,
137 enableDebug: false,
138 },
139 "Run iOS Hermes - Experimental": {
140 name: "Run iOS Hermes - Experimental",
141 cwd: "${workspaceFolder}",
142 type: DEBUG_TYPES.REACT_NATIVE_DIRECT,
143 request: "launch",
144 platform: PlatformType.iOS,
145 enableDebug: false,
146 },
147 "Run Direct iOS - Experimental": {
148 name: "Run Direct iOS - Experimental",
149 cwd: "${workspaceFolder}",
150 type: DEBUG_TYPES.REACT_NATIVE_DIRECT,
151 request: "launch",
152 platform: PlatformType.iOS,
153 enableDebug: false,
154 useHermesEngine: false,
155 target: "device",
156 },
157 };
158
159 private initialPickConfig: ReadonlyArray<vscode.QuickPickItem> = [
160 {
161 label: "Debug Android",
162 description: localize("DebugAndroidConfigDesc", "Run and debug Android application"),
163 },
164 {
165 label: "Run Android",
166 description: localize("RunAndroidConfigDesc", "Run Android application"),
167 },
168 {
169 label: "Debug iOS",
170 description: localize("DebugiOSConfigDesc", "Run and debug iOS application"),
171 },
172 {
173 label: "Run iOS",
174 description: localize("RuniOSConfigDesc", "Run iOS application"),
175 },
176 {
177 label: "Debug Windows",
178 description: localize("DebugWindowsConfigDesc", "Run and debug Windows application"),
179 },
180 {
181 label: "Debug macOS",
182 description: localize("DebugmacOSConfigDesc", "Run and debug macOS application"),
183 },
184 {
185 label: "Attach to packager",
186 description: localize(
187 "AttachToPackagerConfigDesc",
188 "Attach to already working application packager",
189 ),
190 },
191 {
192 label: "Debug in Exponent",
193 description: localize(
194 "DebugExpoConfigDesc",
195 "Debug Expo application or React Native application in Expo",
196 ),
197 },
198 {
199 label: "Debug Android Hermes - Experimental",
200 description: localize(
201 "DebugAndroidHermesConfigDesc",
202 "Run and debug Android Hermes application",
203 ),
204 },
205 {
206 label: "Run Android Hermes - Experimental",
207 description: localize("RunAndroidHermesConfigDesc", "Run Android Hermes application"),
208 },
209 {
210 label: "Debug iOS Hermes - Experimental",
211 description: localize(
212 "DebugIosHermesConfigDesc",
213 "Run and debug iOS Hermes application",
214 ),
215 },
216 {
217 label: "Run iOS Hermes - Experimental",
218 description: localize("RunIosHermesConfigDesc", "Run iOS Hermes application"),
219 },
220 {
221 label: "Debug macOS Hermes - Experimental",
222 description: localize(
223 "DebugMacOSHermesConfigDesc",
224 "Run and debug macOS Hermes application",
225 ),
226 },
227 {
228 label: "Attach to Hermes application - Experimental",
229 description: localize(
230 "AttachToPackagerHermesConfigDesc",
231 "Attach to already working React Native Hermes application on Android directly",
232 ),
233 },
234 {
235 label: "Debug Direct iOS - Experimental",
236 description: localize(
237 "DebugDirectiOSConfigDesc",
238 "Run and debug iOS application directly",
239 ),
240 },
241 {
242 label: "Run Direct iOS - Experimental",
243 description: localize(
244 "RunDirectiOSConfigDesc",
245 "Run iOS application with direct debugging support",
246 ),
247 },
248 {
249 label: "Attach to Direct iOS - Experimental",
250 description: localize(
251 "AttachToPackageriOSConfigDesc",
252 "Attach to already working React Native iOS application directly",
253 ),
254 },
255 ];
256
257 private sequentialPickConfig: ReadonlyArray<DebugConfigurationQuickPickItem> = [
258 {
259 label: "Run application",
260 description: localize(
261 "RunApplicationScenario",
262 "Run React Native application without debugging",
263 ),
264 type: DebugScenarioType.RunApp,
265 },
266 {
267 label: "Debug application",
268 description: localize("DebugApplicationScenario", "Debug React Native application"),
269 type: DebugScenarioType.DebugApp,
270 },
271 {
272 label: "Attach to application",
273 description: localize(
274 "AttachApplicationScenario",
275 "Attach to running React Native application",
276 ),
277 type: DebugScenarioType.AttachApp,
278 },
279 ];
280
281 public async provideDebugConfigurations(
282 folder: vscode.WorkspaceFolder | undefined, // eslint-disable-line @typescript-eslint/no-unused-vars
283 token?: vscode.CancellationToken, // eslint-disable-line @typescript-eslint/no-unused-vars
284 ): Promise<vscode.DebugConfiguration[]> {
285 return new Promise<vscode.DebugConfiguration[]>(resolve => {
286 const configPicker = this.prepareDebugConfigPicker();
287 const disposables: vscode.Disposable[] = [];
288 const pickHandler = () => {
289 let chosenConfigsEvent = TelemetryHelper.createTelemetryEvent(
290 "chosenDebugConfigurations",
291 );
292 let selected: string[] = configPicker.selectedItems.map(element => element.label);
293 chosenConfigsEvent.properties["selectedItems"] = selected;
294 Telemetry.send(chosenConfigsEvent);
295 const launchConfig = this.gatherDebugScenarios(selected);
296 disposables.forEach(d => d.dispose());
297 resolve(launchConfig);
298 };
299
300 disposables.push(
301 configPicker.onDidAccept(pickHandler),
302 configPicker.onDidHide(pickHandler),
303 configPicker,
304 );
305
306 configPicker.show();
307 });
308 }
309
310 public async provideDebugConfigurationSequentially(
311 folder: vscode.WorkspaceFolder | undefined,
312 token?: vscode.CancellationToken,
313 ): Promise<vscode.DebugConfiguration | undefined> {
314 const config: Partial<ILaunchRequestArgs> = {};
315 const state = { config, scenarioType: DebugScenarioType.DebugApp, folder, token };
316
317 const multiStep = new MultiStepInput<DebugConfigurationState>();
318 await multiStep.run((input, s) => this.pickDebugConfiguration(input, s), state);
319
320 if (Object.keys(state.config).length === 0) {
321 return;
322 } else {
323 if (state.config.type === DEBUG_TYPES.REACT_NATIVE_DIRECT) {
324 state.config.name = DebugScenarioNameGenerator.createScenarioName(
325 state.scenarioType,
326 state.config.type,
327 state.config.platform,
328 state.config.useHermesEngine !== false,
329 true,
330 );
331 } else {
332 state.config.name = DebugScenarioNameGenerator.createScenarioName(
333 state.scenarioType,
334 state.config.type || DEBUG_TYPES.REACT_NATIVE,
335 state.config.platform,
336 );
337 }
338 return state.config as vscode.DebugConfiguration;
339 }
340 }
341
342 private async pickDebugConfiguration(
343 input: IMultiStepInput<DebugConfigurationState>,
344 state: DebugConfigurationState,
345 ): Promise<InputStep<DebugConfigurationState> | void> {
346 state.config = {};
347 const pick = await input.showQuickPick<
348 DebugConfigurationQuickPickItem,
349 IQuickPickParameters<DebugConfigurationQuickPickItem>
350 >({
351 title: localize("DebugConfigQuickPickSequentialLabel", "Select a debug configuration"),
352 placeholder: "Debug Configuration",
353 activeItem: this.sequentialPickConfig[0],
354 items: this.sequentialPickConfig,
355 });
356 if (pick) {
357 const provider = ConfigProviderFactory.create(pick.type);
358 return provider.buildConfiguration.bind(provider);
359 }
360 }
361
362 private gatherDebugScenarios(selectedItems: string[]): vscode.DebugConfiguration[] {
363 let launchConfig: vscode.DebugConfiguration[] = selectedItems.map(
364 element => this.debugConfigurations[element],
365 );
366 return launchConfig;
367 }
368
369 private prepareDebugConfigPicker(): vscode.QuickPick<vscode.QuickPickItem> {
370 const debugConfigPicker = vscode.window.createQuickPick();
371 debugConfigPicker.canSelectMany = true;
372 debugConfigPicker.ignoreFocusOut = true;
373 debugConfigPicker.title = localize(
374 "DebugConfigQuickPickLabel",
375 "Pick debug configurations",
376 );
377 debugConfigPicker.items = this.initialPickConfig;
378 // QuickPickItem property `picked` doesn't work, so this line will check first item in the list
379 // which is supposed to be Debug Android
380 debugConfigPicker.selectedItems = [this.initialPickConfig[0]];
381 return debugConfigPicker;
382 }
383}
384