microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
1.11.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/debuggingConfiguration/reactNativeDebugDynamicConfigProvider.ts

168lines · 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[DEBUG_CONFIGURATION_NAMES.DEBUG_ANDROID_HERMES];
73 delete debugConfigurationsToShow[DEBUG_CONFIGURATION_NAMES.RUN_ANDROID_HERMES];
74 }
75
76 if (!iOSHermesEnabled) {
77 delete debugConfigurationsToShow[DEBUG_CONFIGURATION_NAMES.DEBUG_IOS_HERMES];
78 delete debugConfigurationsToShow[DEBUG_CONFIGURATION_NAMES.RUN_IOS_HERMES];
79 }
80
81 if (
82 !androidHermesEnabled &&
83 !iOSHermesEnabled &&
84 !macOSHermesEnabled &&
85 !windowsHermesEnabled
86 ) {
87 delete debugConfigurationsToShow[
88 DEBUG_CONFIGURATION_NAMES.ATTACH_TO_HERMES_APPLICATION
89 ];
90 }
91 }
92
93 const debugConfigurationsToShowList = Object.values(debugConfigurationsToShow);
94 debugConfigurationsToShowList.forEach(config => {
95 config.isDynamic = true;
96 });
97
98 return debugConfigurationsToShowList;
99 }
100
101 public async resolveDebugConfiguration(
102 folder: vscode.WorkspaceFolder | undefined,
103 config: vscode.DebugConfiguration,
104 token?: vscode.CancellationToken,
105 ): Promise<vscode.ProviderResult<vscode.DebugConfiguration>> {
106 if (config.isDynamic) {
107 const chosenConfigsEvent = TelemetryHelper.createTelemetryEvent(
108 "chosenDynamicDebugConfiguration",
109 {
110 selectedConfiguration: config.name,
111 },
112 );
113 Telemetry.send(chosenConfigsEvent);
114 if (config.request === "attach") {
115 await this.configureAttachScenario(folder, config, token);
116 }
117 if (config.platform === PlatformType.Exponent) {
118 await this.configureExpoScenario(folder, config, token);
119 }
120 }
121
122 return config;
123 }
124
125 private async configureExpoScenario(
126 folder: vscode.WorkspaceFolder | undefined,
127 config: vscode.DebugConfiguration,
128 token?: vscode.CancellationToken,
129 ): Promise<vscode.DebugConfiguration> {
130 const state = { config, scenarioType: DebugScenarioType.DebugApp, folder, token };
131 const picker = new MultiStepInput<DebugConfigurationState>();
132 const configurationProviderHelper = new ConfigurationProviderHelper();
133 await picker.run(async (input, s) => {
134 await configurationProviderHelper.selectExpoHostType(input, s.config, 1, 1);
135 }, state);
136
137 return config;
138 }
139
140 private async configureAttachScenario(
141 folder: vscode.WorkspaceFolder | undefined,
142 config: vscode.DebugConfiguration,
143 token?: vscode.CancellationToken,
144 ): Promise<vscode.DebugConfiguration> {
145 const state = { config, scenarioType: DebugScenarioType.AttachApp, folder, token };
146 const picker = new MultiStepInput<DebugConfigurationState>();
147 const configurationProviderHelper = new ConfigurationProviderHelper();
148
149 const configurePort = async (
150 input: MultiStepInput<DebugConfigurationState>,
151 config: Partial<ILaunchRequestArgs>,
152 ): Promise<InputStep<DebugConfigurationState> | void> => {
153 await configurationProviderHelper.configurePort(input, config, 2, 2);
154 };
155
156 const configureAddress = async (
157 input: MultiStepInput<DebugConfigurationState>,
158 config: Partial<ILaunchRequestArgs>,
159 ): Promise<InputStep<DebugConfigurationState> | void> => {
160 await configurationProviderHelper.configureAddress(input, config, 1, 2, "localhost");
161 return () => configurePort(input, config);
162 };
163
164 await picker.run((input, s) => configureAddress(input, s.config), state);
165
166 return config;
167 }
168}
169