microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
70cfd5650973cc6872aaae01ea2db7a924e6b67b

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/debugger/direct/directDebugAdapter.ts

201lines · modeblame

549baae2RedMickey6 years ago1// 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 path from "path";
5import { ReactNativeProjectHelper } from "../../common/reactNativeProjectHelper";
6import { ErrorHelper } from "../../common/error/errorHelper";
7import { getExtensionVersion } from "../../common/extensionHelper";
8import { ILaunchArgs } from "../../extension/launchArgs";
9import { getProjectRoot } from "../nodeDebugWrapper";
10import { Telemetry } from "../../common/telemetry";
11import { OutputEvent, Logger } from "vscode-debugadapter";
12import { TelemetryHelper } from "../../common/telemetryHelper";
13import { RemoteTelemetryReporter } from "../../common/telemetryReporters";
14import { ChromeDebugAdapter, ChromeDebugSession, IChromeDebugSessionOpts, IAttachRequestArgs, logger } from "vscode-chrome-debug-core";
15import { InternalErrorCode } from "../../common/error/internalErrorCode";
16import { RemoteExtension } from "../../common/remoteExtension";
17import { DebugProtocol } from "vscode-debugprotocol";
18import { getLoggingDirectory } from "../../extension/log/LogHelper";
19import * as nls from "vscode-nls";
20import * as Q from "q";
21const localize = nls.loadMessageBundle();
22
23export interface IDirectAttachRequestArgs extends IAttachRequestArgs, ILaunchArgs {
24cwd: string; /* Automatically set by VS Code to the currently opened folder */
25}
26
27export interface IDirectLaunchRequestArgs extends DebugProtocol.LaunchRequestArguments, IDirectAttachRequestArgs { }
28
29export class DirectDebugAdapter extends ChromeDebugAdapter {
30
31private outputLogger: (message: string, error?: boolean | string) => void;
32private projectRootPath: string;
33private remoteExtension: RemoteExtension;
34private isSettingsInitialized: boolean; // used to prevent parameters reinitialization when attach is called from launch function
35private previousAttachArgs: IDirectAttachRequestArgs;
36
37public constructor(opts: IChromeDebugSessionOpts, debugSession: ChromeDebugSession) {
38super(opts, debugSession);
39this.outputLogger = (message: string, error?: boolean | string) => {
40let category = "console";
41if (error === true) {
42category = "stderr";
43}
44if (typeof error === "string") {
45category = error;
46}
47
48let newLine = "\n";
49if (category === "stdout" || category === "stderr") {
50newLine = "";
51}
52debugSession.sendEvent(new OutputEvent(message + newLine, category));
53};
54
55this.isSettingsInitialized = false;
56}
57
58public launch(launchArgs: IDirectLaunchRequestArgs): Promise<void> {
ba953e9fRedMickey6 years ago59let extProps = {
549baae2RedMickey6 years ago60platform: {
61value: launchArgs.platform,
62isPii: false,
63},
64isDirect: {
65value: true,
66isPii: false,
67},
68};
69
70return new Promise<void>((resolve, reject) => this.initializeSettings(launchArgs)
71.then(() => {
ba953e9fRedMickey6 years ago72this.outputLogger("Launching the application");
73logger.verbose(`Launching the application: ${JSON.stringify(launchArgs, null , 2)}`);
74return ReactNativeProjectHelper.getReactNativeVersion(launchArgs.cwd)
75.then(version => {
76extProps = TelemetryHelper.addReactNativeVersionToEventProperties(version, extProps);
77return TelemetryHelper.generate("launch", extProps, (generator) => {
78return this.remoteExtension.launch({ "arguments": launchArgs })
79.then(() => {
80return this.remoteExtension.getPackagerPort(launchArgs.cwd);
81})
82.then((packagerPort: number) => {
83launchArgs.port = launchArgs.port || packagerPort;
84this.attach(launchArgs).then(() => {
85resolve();
86}).catch((e) => reject(e));
87}).catch((e) => reject(e));
549baae2RedMickey6 years ago88})
ba953e9fRedMickey6 years ago89.catch((err) => {
90this.outputLogger("An error occurred while launching the application. " + err.message || err, true);
91this.cleanUp();
92reject(err);
93});
94});
549baae2RedMickey6 years ago95}));
96}
97
98public attach(attachArgs: IDirectAttachRequestArgs): Promise<void> {
ba953e9fRedMickey6 years ago99let extProps = {
549baae2RedMickey6 years ago100platform: {
101value: attachArgs.platform,
102isPii: false,
103},
104isDirect: {
105value: true,
106isPii: false,
107},
108};
109
110this.previousAttachArgs = attachArgs;
111
112return new Promise<void>((resolve, reject) => this.initializeSettings(attachArgs)
113.then(() => {
ba953e9fRedMickey6 years ago114this.outputLogger("Attaching to the application");
115logger.verbose(`Attaching to the application: ${JSON.stringify(attachArgs, null , 2)}`);
116return ReactNativeProjectHelper.getReactNativeVersion(attachArgs.cwd)
117.then(version => {
118extProps = TelemetryHelper.addReactNativeVersionToEventProperties(version, extProps);
119return TelemetryHelper.generate("attach", extProps, (generator) => {
120return this.remoteExtension.getPackagerPort(attachArgs.cwd)
121.then((packagerPort: number) => {
122attachArgs.port = attachArgs.port || packagerPort;
123this.outputLogger(`Connecting to ${attachArgs.port} port`);
124const attachArguments = Object.assign({}, attachArgs, {
125address: "localhost",
126port: attachArgs.port,
127restart: true,
128request: "attach",
129remoteRoot: undefined,
130localRoot: undefined,
131});
132super.attach(attachArguments).then(() => {
133this.outputLogger("The debugger attached successfully");
134resolve();
135}).catch((e) => reject(e));
136}).catch((e) => reject(e));
137})
138.catch((err) => {
139this.outputLogger("An error occurred while attaching to the debugger. " + err.message || err, true);
140this.cleanUp();
141reject(err);
142});
143});
549baae2RedMickey6 years ago144}));
145}
146
147public disconnect(args: DebugProtocol.DisconnectArguments): void {
148this.cleanUp();
149super.disconnect(args);
150}
151
152private initializeSettings(args: any): Q.Promise<any> {
153if (!this.isSettingsInitialized) {
154let chromeDebugCoreLogs = getLoggingDirectory();
155if (chromeDebugCoreLogs) {
156chromeDebugCoreLogs = path.join(chromeDebugCoreLogs, "ChromeDebugCoreLogs.txt");
157}
158let logLevel: string = args.trace;
159if (logLevel) {
160logLevel = logLevel.replace(logLevel[0], logLevel[0].toUpperCase());
161logger.setup(Logger.LogLevel[logLevel], chromeDebugCoreLogs || false);
162} else {
163logger.setup(Logger.LogLevel.Log, chromeDebugCoreLogs || false);
164}
165
166if (!args.sourceMaps) {
167args.sourceMaps = true;
168}
169
170const projectRootPath = getProjectRoot(args);
171return ReactNativeProjectHelper.isReactNativeProject(projectRootPath)
172.then((result) => {
173if (!result) {
174throw ErrorHelper.getInternalError(InternalErrorCode.NotInReactNativeFolderError);
175}
176this.projectRootPath = projectRootPath;
177this.remoteExtension = RemoteExtension.atProjectRootPath(this.projectRootPath);
178const version = getExtensionVersion();
179
180// Start to send telemetry
181(this._session as any).getTelemetryReporter().reassignTo(new RemoteTelemetryReporter(
182"react-native-tools", version, Telemetry.APPINSIGHTS_INSTRUMENTATIONKEY, this.projectRootPath));
183
184this.isSettingsInitialized = true;
185
186return void 0;
187});
188} else {
189return Q.resolve<void>(void 0);
190}
191}
192
193private cleanUp() {
194if (this.previousAttachArgs.platform === "android") {
195this.remoteExtension.stopMonitoringLogcat()
196.catch(reason => logger.warn(localize("CouldNotStopMonitoringLogcat", "Couldn't stop monitoring logcat: {0}", reason.message || reason)))
197.finally(() => super.disconnect({terminateDebuggee: true}));
198}
199}
200
201}