microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
dev/v-peq/remove-ios-relative-project-path

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/debuggingConfiguration/reactNativeDebugConfigProvider.ts

305lines · 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,
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,
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,
107 description: localize(
108 "DebugMacOSHermesConfigDesc",
109 "Run and debug macOS Hermes application",
110 ),
111 },
112 {
113 label: DEBUG_CONFIGURATION_NAMES.DEBUG_WINDOWS_HERMES,
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 if (state.config.platform === "exponent") {
230 state.config.name = DebugScenarioNameGenerator.createScenarioName(
231 state.scenarioType,
232 state.config.type,
233 state.config.platform,
234 state.config.useHermesEngine !== false,
235 false,
236 state.config.expoPlatformType,
237 );
238 } else {
239 state.config.name = DebugScenarioNameGenerator.createScenarioName(
240 state.scenarioType,
241 state.config.type,
242 state.config.platform,
243 state.config.useHermesEngine !== false,
244 );
245 }
246 } else {
247 state.config.name = DebugScenarioNameGenerator.createScenarioName(
248 state.scenarioType,
249 state.config.type || DEBUG_TYPES.REACT_NATIVE,
250 state.config.platform,
251 );
252 }
253 } else {
254 state.config.name = DebugScenarioNameGenerator.createScenarioName(
255 state.scenarioType,
256 state.config.type || DEBUG_TYPES.REACT_NATIVE,
257 state.config.platform,
258 );
259 }
260
261 return state.config as vscode.DebugConfiguration;
262 }
263
264 private async pickDebugConfiguration(
265 input: IMultiStepInput<DebugConfigurationState>,
266 state: DebugConfigurationState,
267 ): Promise<InputStep<DebugConfigurationState> | void> {
268 state.config = {};
269 const pick = await input.showQuickPick<
270 DebugConfigurationQuickPickItem,
271 IQuickPickParameters<DebugConfigurationQuickPickItem>
272 >({
273 title: localize("DebugConfigQuickPickSequentialLabel", "Select a debug configuration"),
274 placeholder: "Debug Configuration",
275 activeItem: this.sequentialPickConfig[0],
276 items: this.sequentialPickConfig,
277 });
278 if (pick) {
279 const provider = ConfigProviderFactory.create(pick.type);
280 return provider.buildConfiguration.bind(provider);
281 }
282 }
283
284 private gatherDebugScenarios(selectedItems: string[]): vscode.DebugConfiguration[] {
285 const launchConfig: vscode.DebugConfiguration[] = selectedItems.map(
286 element => debugConfigurations[element],
287 );
288 return launchConfig;
289 }
290
291 private prepareDebugConfigPicker(): vscode.QuickPick<vscode.QuickPickItem> {
292 const debugConfigPicker = vscode.window.createQuickPick();
293 debugConfigPicker.canSelectMany = true;
294 debugConfigPicker.ignoreFocusOut = true;
295 debugConfigPicker.title = localize(
296 "DebugConfigQuickPickLabel",
297 "Pick debug configurations",
298 );
299 debugConfigPicker.items = this.initialPickConfig;
300 // QuickPickItem property `picked` doesn't work, so this line will check first item in the list
301 // which is supposed to be Debug Android
302 debugConfigPicker.selectedItems = [this.initialPickConfig[0]];
303 return debugConfigPicker;
304 }
305}
306