microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
c78564627d05eb04bd03fb8d3978871935d0c077

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/debuggingConfiguration/reactNativeDebugConfigProvider.ts

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