microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
1.12.2

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/debuggingConfiguration/reactNativeDebugConfigProvider.ts

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