microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
dev/v-peq/add-expo-packager-command-tests

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/debuggingConfiguration/reactNativeDebugDynamicConfigProvider.ts

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