microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
4cd259621ddfbd348fade892a2f3ee87fd1924c5

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/debuggingConfiguration/reactNativeDebugConfigProvider.ts

397lines · 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 "Debug Windows Hermes - Experimental": {
116 name: "Debug Windows Hermes - Experimental",
117 cwd: "${workspaceFolder}",
118 type: DEBUG_TYPES.REACT_NATIVE_DIRECT,
119 request: "launch",
120 platform: PlatformType.Windows,
121 },
122 "Run Android": {
123 name: "Run Android",
124 cwd: "${workspaceFolder}",
125 type: DEBUG_TYPES.REACT_NATIVE,
126 request: "launch",
127 platform: PlatformType.Android,
128 enableDebug: false,
129 },
130 "Run iOS": {
131 name: "Run iOS",
132 cwd: "${workspaceFolder}",
133 type: DEBUG_TYPES.REACT_NATIVE,
134 request: "launch",
135 platform: PlatformType.iOS,
136 enableDebug: false,
137 },
138 "Run Android Hermes - Experimental": {
139 name: "Run Android Hermes - Experimental",
140 cwd: "${workspaceFolder}",
141 type: DEBUG_TYPES.REACT_NATIVE_DIRECT,
142 request: "launch",
143 platform: PlatformType.Android,
144 enableDebug: false,
145 },
146 "Run iOS Hermes - Experimental": {
147 name: "Run iOS Hermes - Experimental",
148 cwd: "${workspaceFolder}",
149 type: DEBUG_TYPES.REACT_NATIVE_DIRECT,
150 request: "launch",
151 platform: PlatformType.iOS,
152 enableDebug: false,
153 },
154 "Run Direct iOS - Experimental": {
155 name: "Run Direct iOS - Experimental",
156 cwd: "${workspaceFolder}",
157 type: DEBUG_TYPES.REACT_NATIVE_DIRECT,
158 request: "launch",
159 platform: PlatformType.iOS,
160 enableDebug: false,
161 useHermesEngine: false,
162 target: "device",
163 },
164 };
165
166 private initialPickConfig: ReadonlyArray<vscode.QuickPickItem> = [
167 {
168 label: "Debug Android",
169 description: localize("DebugAndroidConfigDesc", "Run and debug Android application"),
170 },
171 {
172 label: "Run Android",
173 description: localize("RunAndroidConfigDesc", "Run Android application"),
174 },
175 {
176 label: "Debug iOS",
177 description: localize("DebugiOSConfigDesc", "Run and debug iOS application"),
178 },
179 {
180 label: "Run iOS",
181 description: localize("RuniOSConfigDesc", "Run iOS application"),
182 },
183 {
184 label: "Debug Windows",
185 description: localize("DebugWindowsConfigDesc", "Run and debug Windows application"),
186 },
187 {
188 label: "Debug macOS",
189 description: localize("DebugmacOSConfigDesc", "Run and debug macOS application"),
190 },
191 {
192 label: "Attach to packager",
193 description: localize(
194 "AttachToPackagerConfigDesc",
195 "Attach to already working application packager",
196 ),
197 },
198 {
199 label: "Debug in Exponent",
200 description: localize(
201 "DebugExpoConfigDesc",
202 "Debug Expo application or React Native application in Expo",
203 ),
204 },
205 {
206 label: "Debug Android Hermes - Experimental",
207 description: localize(
208 "DebugAndroidHermesConfigDesc",
209 "Run and debug Android Hermes application",
210 ),
211 },
212 {
213 label: "Run Android Hermes - Experimental",
214 description: localize("RunAndroidHermesConfigDesc", "Run Android Hermes application"),
215 },
216 {
217 label: "Debug iOS Hermes - Experimental",
218 description: localize(
219 "DebugIosHermesConfigDesc",
220 "Run and debug iOS Hermes application",
221 ),
222 },
223 {
224 label: "Run iOS Hermes - Experimental",
225 description: localize("RunIosHermesConfigDesc", "Run iOS Hermes application"),
226 },
227 {
228 label: "Debug macOS Hermes - Experimental",
229 description: localize(
230 "DebugMacOSHermesConfigDesc",
231 "Run and debug macOS Hermes application",
232 ),
233 },
234 {
235 label: "Debug Windows Hermes - Experimental",
236 description: localize(
237 "DebugWindowsHermesConfigDesc",
238 "Run and debug Windows Hermes application",
239 ),
240 },
241 {
242 label: "Attach to Hermes application - Experimental",
243 description: localize(
244 "AttachToPackagerHermesConfigDesc",
245 "Attach to already working React Native Hermes application on Android directly",
246 ),
247 },
248 {
249 label: "Debug Direct iOS - Experimental",
250 description: localize(
251 "DebugDirectiOSConfigDesc",
252 "Run and debug iOS application directly",
253 ),
254 },
255 {
256 label: "Run Direct iOS - Experimental",
257 description: localize(
258 "RunDirectiOSConfigDesc",
259 "Run iOS application with direct debugging support",
260 ),
261 },
262 {
263 label: "Attach to Direct iOS - Experimental",
264 description: localize(
265 "AttachToPackageriOSConfigDesc",
266 "Attach to already working React Native iOS application directly",
267 ),
268 },
269 ];
270
271 private sequentialPickConfig: ReadonlyArray<DebugConfigurationQuickPickItem> = [
272 {
273 label: "Run application",
274 description: localize(
275 "RunApplicationScenario",
276 "Run React Native application without debugging",
277 ),
278 type: DebugScenarioType.RunApp,
279 },
280 {
281 label: "Debug application",
282 description: localize("DebugApplicationScenario", "Debug React Native application"),
283 type: DebugScenarioType.DebugApp,
284 },
285 {
286 label: "Attach to application",
287 description: localize(
288 "AttachApplicationScenario",
289 "Attach to running React Native application",
290 ),
291 type: DebugScenarioType.AttachApp,
292 },
293 ];
294
295 public async provideDebugConfigurations(
296 folder: vscode.WorkspaceFolder | undefined, // eslint-disable-line @typescript-eslint/no-unused-vars
297 token?: vscode.CancellationToken, // eslint-disable-line @typescript-eslint/no-unused-vars
298 ): Promise<vscode.DebugConfiguration[]> {
299 return new Promise<vscode.DebugConfiguration[]>(resolve => {
300 const configPicker = this.prepareDebugConfigPicker();
301 const disposables: vscode.Disposable[] = [];
302 const pickHandler = () => {
303 let chosenConfigsEvent = TelemetryHelper.createTelemetryEvent(
304 "chosenDebugConfigurations",
305 );
306 let selected: string[] = configPicker.selectedItems.map(element => element.label);
307 chosenConfigsEvent.properties["selectedItems"] = selected;
308 Telemetry.send(chosenConfigsEvent);
309 const launchConfig = this.gatherDebugScenarios(selected);
310 disposables.forEach(d => d.dispose());
311 resolve(launchConfig);
312 };
313
314 disposables.push(
315 configPicker.onDidAccept(pickHandler),
316 configPicker.onDidHide(pickHandler),
317 configPicker,
318 );
319
320 configPicker.show();
321 });
322 }
323
324 public async provideDebugConfigurationSequentially(
325 folder: vscode.WorkspaceFolder | undefined,
326 token?: vscode.CancellationToken,
327 ): Promise<vscode.DebugConfiguration | undefined> {
328 const config: Partial<ILaunchRequestArgs> = {};
329 const state = { config, scenarioType: DebugScenarioType.DebugApp, folder, token };
330
331 const multiStep = new MultiStepInput<DebugConfigurationState>();
332 await multiStep.run((input, s) => this.pickDebugConfiguration(input, s), state);
333
334 if (Object.keys(state.config).length === 0) {
335 return;
336 } else {
337 if (state.config.type === DEBUG_TYPES.REACT_NATIVE_DIRECT) {
338 state.config.name = DebugScenarioNameGenerator.createScenarioName(
339 state.scenarioType,
340 state.config.type,
341 state.config.platform,
342 state.config.useHermesEngine !== false,
343 true,
344 );
345 } else {
346 state.config.name = DebugScenarioNameGenerator.createScenarioName(
347 state.scenarioType,
348 state.config.type || DEBUG_TYPES.REACT_NATIVE,
349 state.config.platform,
350 );
351 }
352 return state.config as vscode.DebugConfiguration;
353 }
354 }
355
356 private async pickDebugConfiguration(
357 input: IMultiStepInput<DebugConfigurationState>,
358 state: DebugConfigurationState,
359 ): Promise<InputStep<DebugConfigurationState> | void> {
360 state.config = {};
361 const pick = await input.showQuickPick<
362 DebugConfigurationQuickPickItem,
363 IQuickPickParameters<DebugConfigurationQuickPickItem>
364 >({
365 title: localize("DebugConfigQuickPickSequentialLabel", "Select a debug configuration"),
366 placeholder: "Debug Configuration",
367 activeItem: this.sequentialPickConfig[0],
368 items: this.sequentialPickConfig,
369 });
370 if (pick) {
371 const provider = ConfigProviderFactory.create(pick.type);
372 return provider.buildConfiguration.bind(provider);
373 }
374 }
375
376 private gatherDebugScenarios(selectedItems: string[]): vscode.DebugConfiguration[] {
377 let launchConfig: vscode.DebugConfiguration[] = selectedItems.map(
378 element => this.debugConfigurations[element],
379 );
380 return launchConfig;
381 }
382
383 private prepareDebugConfigPicker(): vscode.QuickPick<vscode.QuickPickItem> {
384 const debugConfigPicker = vscode.window.createQuickPick();
385 debugConfigPicker.canSelectMany = true;
386 debugConfigPicker.ignoreFocusOut = true;
387 debugConfigPicker.title = localize(
388 "DebugConfigQuickPickLabel",
389 "Pick debug configurations",
390 );
391 debugConfigPicker.items = this.initialPickConfig;
392 // QuickPickItem property `picked` doesn't work, so this line will check first item in the list
393 // which is supposed to be Debug Android
394 debugConfigPicker.selectedItems = [this.initialPickConfig[0]];
395 return debugConfigPicker;
396 }
397}
398