microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
1.9.2

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/debuggingConfiguration/reactNativeDebugDynamicConfigProvider.ts

176lines · 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 { SettingsHelper } from "../settingsHelper";
6import { TelemetryHelper } from "../../common/telemetryHelper";
7import { Telemetry } from "../../common/telemetry";
8import { ProjectVersionHelper } from "../../common/projectVersionHelper";
9import { ReactNativeProjectHelper } from "../../common/reactNativeProjectHelper";
10import { PlatformType } from "../launchArgs";
11import { ILaunchRequestArgs } from "../../debugger/debugSessionBase";
12import { ConfigurationProviderHelper } from "../../common/configurationProviderHelper";
13import { MultiStepInput, InputStep } from "./multiStepInput";
14import {
15 debugConfigurations,
16 DEBUG_CONFIGURATION_NAMES,
17 DebugScenarioType,
18 DebugConfigurationState,
19} from "./debugConfigTypesAndConstants";
20
21export class ReactNativeDebugDynamicConfigProvider implements vscode.DebugConfigurationProvider {
22 public async provideDebugConfigurations(
23 folder: vscode.WorkspaceFolder | undefined,
24 token?: vscode.CancellationToken, // eslint-disable-line @typescript-eslint/no-unused-vars
25 ): Promise<vscode.DebugConfiguration[]> {
26 const debugConfigurationsToShow = Object.assign({}, debugConfigurations);
27
28 if (folder) {
29 const rootPath = folder.uri.fsPath;
30 const projectRootPath = SettingsHelper.getReactNativeProjectRoot(rootPath);
31 const versions =
32 await ProjectVersionHelper.tryToGetRNSemverValidVersionsFromProjectPackage(
33 projectRootPath,
34 ProjectVersionHelper.generateAllAdditionalPackages(),
35 projectRootPath,
36 );
37
38 let macOSHermesEnabled = false;
39 let windowsHermesEnabled = false;
40 const androidHermesEnabled = ReactNativeProjectHelper.isAndroidHermesEnabled(rootPath);
41 const iOSHermesEnabled = ReactNativeProjectHelper.isIOSHermesEnabled(rootPath);
42
43 if (ProjectVersionHelper.isVersionError(versions.reactNativeWindowsVersion)) {
44 delete debugConfigurationsToShow[DEBUG_CONFIGURATION_NAMES.DEBUG_WINDOWS];
45 delete debugConfigurationsToShow[
46 DEBUG_CONFIGURATION_NAMES.DEBUG_WINDOWS_HERMES_EXPERIMENTAL
47 ];
48 } else {
49 windowsHermesEnabled = ReactNativeProjectHelper.isWindowsHermesEnabled(rootPath);
50 if (!windowsHermesEnabled) {
51 delete debugConfigurationsToShow[
52 DEBUG_CONFIGURATION_NAMES.DEBUG_WINDOWS_HERMES_EXPERIMENTAL
53 ];
54 }
55 }
56
57 if (ProjectVersionHelper.isVersionError(versions.reactNativeMacOSVersion)) {
58 delete debugConfigurationsToShow[DEBUG_CONFIGURATION_NAMES.DEBUG_MACOS];
59 delete debugConfigurationsToShow[
60 DEBUG_CONFIGURATION_NAMES.DEBUG_MACOS_HERMES_EXPERIMENTAL
61 ];
62 } else {
63 macOSHermesEnabled = ReactNativeProjectHelper.isMacOSHermesEnabled(rootPath);
64 if (!macOSHermesEnabled) {
65 delete debugConfigurationsToShow[
66 DEBUG_CONFIGURATION_NAMES.DEBUG_MACOS_HERMES_EXPERIMENTAL
67 ];
68 }
69 }
70
71 if (!androidHermesEnabled) {
72 delete debugConfigurationsToShow[
73 DEBUG_CONFIGURATION_NAMES.DEBUG_ANDROID_HERMES_EXPERIMENTAL
74 ];
75 delete debugConfigurationsToShow[
76 DEBUG_CONFIGURATION_NAMES.RUN_ANDROID_HERMES_EXPERIMENTAL
77 ];
78 }
79
80 if (!iOSHermesEnabled) {
81 delete debugConfigurationsToShow[
82 DEBUG_CONFIGURATION_NAMES.DEBUG_IOS_HERMES_EXPERIMENTAL
83 ];
84 delete debugConfigurationsToShow[
85 DEBUG_CONFIGURATION_NAMES.RUN_IOS_HERMES_EXPERIMENTAL
86 ];
87 }
88
89 if (
90 !androidHermesEnabled &&
91 !iOSHermesEnabled &&
92 !macOSHermesEnabled &&
93 !windowsHermesEnabled
94 ) {
95 delete debugConfigurationsToShow[
96 DEBUG_CONFIGURATION_NAMES.ATTACH_TO_HERMES_APPLICATION_EXPERIMENTAL
97 ];
98 }
99 }
100
101 const debugConfigurationsToShowList = Object.values(debugConfigurationsToShow);
102 debugConfigurationsToShowList.forEach(config => {
103 config.isDynamic = true;
104 });
105
106 return debugConfigurationsToShowList;
107 }
108
109 public async resolveDebugConfiguration(
110 folder: vscode.WorkspaceFolder | undefined,
111 config: vscode.DebugConfiguration,
112 token?: vscode.CancellationToken,
113 ): Promise<vscode.ProviderResult<vscode.DebugConfiguration>> {
114 if (config.isDynamic) {
115 const chosenConfigsEvent = TelemetryHelper.createTelemetryEvent(
116 "chosenDynamicDebugConfiguration",
117 {
118 selectedConfiguration: config.name,
119 },
120 );
121 Telemetry.send(chosenConfigsEvent);
122 if (config.request === "attach") {
123 await this.configureAttachScenario(folder, config, token);
124 }
125 if (config.platform === PlatformType.Exponent) {
126 await this.configureExpoScenario(folder, config, token);
127 }
128 }
129
130 return config;
131 }
132
133 private async configureExpoScenario(
134 folder: vscode.WorkspaceFolder | undefined,
135 config: vscode.DebugConfiguration,
136 token?: vscode.CancellationToken,
137 ): Promise<vscode.DebugConfiguration> {
138 const state = { config, scenarioType: DebugScenarioType.DebugApp, folder, token };
139 const picker = new MultiStepInput<DebugConfigurationState>();
140 const configurationProviderHelper = new ConfigurationProviderHelper();
141 await picker.run(async (input, s) => {
142 await configurationProviderHelper.selectExpoHostType(input, s.config, 1, 1);
143 }, state);
144
145 return config;
146 }
147
148 private async configureAttachScenario(
149 folder: vscode.WorkspaceFolder | undefined,
150 config: vscode.DebugConfiguration,
151 token?: vscode.CancellationToken,
152 ): Promise<vscode.DebugConfiguration> {
153 const state = { config, scenarioType: DebugScenarioType.AttachApp, folder, token };
154 const picker = new MultiStepInput<DebugConfigurationState>();
155 const configurationProviderHelper = new ConfigurationProviderHelper();
156
157 const configurePort = async (
158 input: MultiStepInput<DebugConfigurationState>,
159 config: Partial<ILaunchRequestArgs>,
160 ): Promise<InputStep<DebugConfigurationState> | void> => {
161 await configurationProviderHelper.configurePort(input, config, 2, 2);
162 };
163
164 const configureAddress = async (
165 input: MultiStepInput<DebugConfigurationState>,
166 config: Partial<ILaunchRequestArgs>,
167 ): Promise<InputStep<DebugConfigurationState> | void> => {
168 await configurationProviderHelper.configureAddress(input, config, 1, 2, "localhost");
169 return () => configurePort(input, config);
170 };
171
172 await picker.run((input, s) => configureAddress(input, s.config), state);
173
174 return config;
175 }
176}
177