Refactor debugger into server, common, and adapter

Summary:
Release note: none
Summary;
- split debugger directory into `server`, `common`, and, `adapter`
- `adapter` and `common` have no dependencies on Prepack and can be moved into Nuclide
- make a copy of invariant.js into `common`
- make `FileIOWrapper` take in an absolute path so it can be used in both server and adapter sides
- Turn relative path into absolute path inside adapter channel
- Create debug communication files if they don't exist

With this refactoring, I can move the `adapter` and `common` directories into Nuclide and submit the code there too
Closes https://github.com/facebook/prepack/pull/1224

Differential Revision: D6510721

Pulled By: JWZ2018

fbshipit-source-id: 2a3f62392187924637aef7fa14260475f4db5de8
This commit is contained in:
Wuhan Zhou 2017-12-07 11:27:47 -08:00 committed by Facebook Github Bot
parent eb689cea14
commit e545270f4e
24 changed files with 90 additions and 70 deletions

View File

@ -18,8 +18,8 @@ import * as evaluators from "./evaluators/index.js";
import * as partialEvaluators from "./partial-evaluators/index.js";
import { Environment } from "./singletons.js";
import { ObjectValue } from "./values/index.js";
import { DebugServer } from "./debugger/Debugger.js";
import type { DebugChannel } from "./debugger/channel/DebugChannel.js";
import { DebugServer } from "./debugger/server/Debugger.js";
import type { DebugChannel } from "./debugger/server/channel/DebugChannel.js";
import simplifyAndRefineAbstractValue from "./utils/simplifier.js";
export default function(opts: RealmOptions = {}, debugChannel: void | DebugChannel = undefined): Realm {

View File

@ -9,31 +9,30 @@
/* @flow */
import {
DebugSession,
LoggingDebugSession,
InitializedEvent,
OutputEvent,
TerminatedEvent,
StoppedEvent,
} from "vscode-debugadapter";
import { DebugSession, InitializedEvent, OutputEvent, TerminatedEvent, StoppedEvent } from "vscode-debugadapter";
import * as DebugProtocol from "vscode-debugprotocol";
import { AdapterChannel } from "./../channel/AdapterChannel.js";
import invariant from "./../../invariant.js";
import { DebugMessage } from "./../channel/DebugMessage.js";
import type { Breakpoint, DebuggerResponse, LaunchRequestArguments, PrepackLaunchArguments } from "./../types.js";
import { DebuggerConstants } from "./../DebuggerConstants.js";
import { AdapterChannel } from "./channel/AdapterChannel.js";
import invariant from "./../common/invariant.js";
import { DebugMessage } from "./../common/channel/DebugMessage.js";
import type {
Breakpoint,
DebuggerResponse,
LaunchRequestArguments,
PrepackLaunchArguments,
} from "./../common/types.js";
import { DebuggerConstants } from "./../common/DebuggerConstants.js";
import path from "path";
/* An implementation of an debugger adapter adhering to the VSCode Debug protocol
* The adapter is responsible for communication between the UI and Prepack
*/
class PrepackDebugSession extends LoggingDebugSession {
class PrepackDebugSession extends DebugSession {
/**
* Creates a new debug adapter that is used for one debug session.
* We configure the default implementation of a debug adapter here.
*/
constructor() {
super("prepack");
super();
this.setDebuggerLinesStartAt1(true);
this.setDebuggerColumnsStartAt1(true);
}
@ -99,12 +98,18 @@ class PrepackDebugSession extends LoggingDebugSession {
// Override
launchRequest(response: DebugProtocol.LaunchResponse, args: LaunchRequestArguments): void {
let inFilePath = path.join(__dirname, "../common/", args.debugInFilePath);
let outFilePath = path.join(__dirname, "../common/", args.debugOutFilePath);
// set up the communication channel
this._adapterChannel = new AdapterChannel(args.debugInFilePath, args.debugOutFilePath);
this._adapterChannel = new AdapterChannel(inFilePath, outFilePath);
this._registerMessageCallbacks();
let launchArgs: PrepackLaunchArguments = {
kind: "launch",
...args,
sourceFile: args.sourceFile,
prepackRuntime: args.prepackRuntime,
prepackArguments: args.prepackArguments,
debugInFilePath: inFilePath,
debugOutFilePath: outFilePath,
outputCallback: (data: Buffer) => {
let outputEvent = new OutputEvent(data.toString(), "stdout");
this.sendEvent(outputEvent);

View File

@ -8,14 +8,14 @@
*/
/* @flow */
import { FileIOWrapper } from "./FileIOWrapper.js";
import { MessageMarshaller } from "./MessageMarshaller.js";
import { FileIOWrapper } from "./../../common/channel/FileIOWrapper.js";
import { MessageMarshaller } from "./../../common/channel/MessageMarshaller.js";
import Queue from "queue-fifo";
import EventEmitter from "events";
import invariant from "./../../invariant.js";
import { DebugMessage } from "./DebugMessage.js";
import invariant from "./../../common/invariant.js";
import { DebugMessage } from "./../../common/channel/DebugMessage.js";
import child_process from "child_process";
import type { Breakpoint, DebuggerResponse, PrepackLaunchArguments } from "./../types.js";
import type { Breakpoint, DebuggerResponse, PrepackLaunchArguments } from "./../../common/types.js";
//Channel used by the debug adapter to communicate with Prepack
export class AdapterChannel {
@ -88,7 +88,6 @@ export class AdapterChannel {
launch(requestID: number, args: PrepackLaunchArguments, callback: DebuggerResponse => void) {
this.sendDebuggerStart(requestID);
this.listenOnFile(this._processPrepackMessage.bind(this));
let prepackCommand = [args.sourceFile].concat(args.prepackArguments);
// Note: here the input file for the adapter is the output file for Prepack, and vice versa.
prepackCommand = prepackCommand.concat([

View File

@ -10,15 +10,15 @@
/* @flow */
import fs from "fs";
import path from "path";
import { MessagePackager } from "./MessagePackager.js";
import invariant from "../../invariant.js";
import invariant from "../invariant.js";
export class FileIOWrapper {
constructor(isAdapter: boolean, inFilePath: string, outFilePath: string) {
// the paths are expected to be relative to Prepack top level directory
this._inFilePath = path.join(__dirname, "../../../", inFilePath);
this._outFilePath = path.join(__dirname, "../../../", outFilePath);
this._inFilePath = inFilePath;
this._outFilePath = outFilePath;
if (!fs.existsSync(this._inFilePath)) fs.openSync(this._inFilePath, "w");
if (!fs.existsSync(this._outFilePath)) fs.openSync(this._outFilePath, "w");
this._packager = new MessagePackager(isAdapter);
this._isAdapter = isAdapter;
}

View File

@ -34,7 +34,7 @@ import type {
EvaluateArguments,
EvaluateResult,
} from "./../types.js";
import invariant from "./../../invariant.js";
import invariant from "./../invariant.js";
import { DebuggerError } from "./../DebuggerError.js";
export class MessageMarshaller {

View File

@ -9,7 +9,7 @@
/* @flow */
import invariant from "../../invariant.js";
import invariant from "../invariant.js";
const LENGTH_SEPARATOR = "--";

View File

@ -0,0 +1,18 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
/* @flow */
export default function invariant(condition: any, format: string): void {
if (condition) return;
let error = new Error(format);
error.name = "Invariant Violation";
throw error;
}

View File

@ -9,9 +9,7 @@
/* @flow */
import type { LexicalEnvironment } from "./../environment.js";
import * as DebugProtocol from "vscode-debugprotocol";
import { ObjectValue, AbstractValue } from "./../values/index.js";
export type DebuggerRequest = {
id: number,
@ -155,8 +153,6 @@ export type EvaluateResult = {
variablesReference: number,
};
// any object that can contain a collection of variables
export type VariableContainer = LexicalEnvironment | ObjectValue | AbstractValue;
export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArguments {
noDebug?: boolean,
sourceFile: string,

View File

@ -13,8 +13,8 @@ import readline from "readline";
import child_process from "child_process";
import * as DebugProtocol from "vscode-debugprotocol";
import { DataHandler } from "./DataHandler.js";
import { DebuggerConstants } from "./../DebuggerConstants";
import { LaunchRequestArguments } from "./../types.js";
import { DebuggerConstants } from "./../common/DebuggerConstants";
import { LaunchRequestArguments } from "./../common/types.js";
export type DebuggerCLIArguments = {
adapterPath: string,

View File

@ -11,9 +11,9 @@
import { PerFileBreakpointMap } from "./PerFileBreakpointMap.js";
import { Breakpoint } from "./Breakpoint.js";
import type { Breakpoint as BreakpointType } from "./types.js";
import type { Breakpoint as BreakpointType } from "./../common/types.js";
import { BabelNode } from "babel-types";
import { IsStatement } from "./../methods/is.js";
import { IsStatement } from "./../../methods/is.js";
// Storing BreakpointStores for all source files
export class BreakpointManager {

View File

@ -11,10 +11,10 @@
import { BreakpointManager } from "./BreakpointManager.js";
import type { BabelNode, BabelNodeSourceLocation } from "babel-types";
import invariant from "../invariant.js";
import invariant from "../common/invariant.js";
import type { DebugChannel } from "./channel/DebugChannel.js";
import { DebugMessage } from "./channel/DebugMessage.js";
import { DebuggerError } from "./DebuggerError.js";
import { DebugMessage } from "./../common/channel/DebugMessage.js";
import { DebuggerError } from "./../common/DebuggerError.js";
import type {
DebuggerRequest,
StackframeArguments,
@ -24,9 +24,9 @@ import type {
VariablesArguments,
EvaluateArguments,
SourceData,
} from "./types.js";
import type { Realm } from "./../realm.js";
import { ExecutionContext } from "./../realm.js";
} from "./../common/types.js";
import type { Realm } from "./../../realm.js";
import { ExecutionContext } from "./../../realm.js";
import { VariableManager } from "./VariableManager.js";
import { SteppingManager } from "./SteppingManager.js";
import type { StoppableObject } from "./StopEventManager.js";
@ -37,7 +37,7 @@ import {
FunctionEnvironmentRecord,
DeclarativeEnvironmentRecord,
ObjectEnvironmentRecord,
} from "./../environment.js";
} from "./../../environment.js";
export class DebugServer {
constructor(channel: DebugChannel, realm: Realm) {

View File

@ -8,10 +8,10 @@
*/
/* @flow */
import type { SourceData } from "./types.js";
import { IsStatement } from "./../methods/is.js";
import type { SourceData } from "./../common/types.js";
import { IsStatement } from "./../../methods/is.js";
import { BabelNode } from "babel-types";
import invariant from "./../invariant.js";
import invariant from "./../common/invariant.js";
export class Stepper {
constructor(filePath: string, line: number, column: number) {

View File

@ -10,9 +10,9 @@
/* @flow */
import { BabelNode } from "babel-types";
import invariant from "./../invariant.js";
import invariant from "./../common/invariant.js";
import { Stepper, StepIntoStepper, StepOverStepper } from "./Stepper.js";
import type { Realm } from "./../realm.js";
import type { Realm } from "./../../realm.js";
import type { StoppableObject } from "./StopEventManager.js";
export class SteppingManager {

View File

@ -9,11 +9,11 @@
/* @flow */
import invariant from "./../invariant.js";
import invariant from "./../common/invariant.js";
import { Breakpoint } from "./Breakpoint.js";
import { Stepper, StepIntoStepper, StepOverStepper } from "./Stepper.js";
import { BabelNode } from "babel-types";
import type { StoppedReason } from "./types.js";
import type { StoppedReason } from "./../common/types.js";
export type StoppableObject = Breakpoint | Stepper;

View File

@ -9,7 +9,7 @@
/* @flow */
import type { VariableContainer, Variable, EvaluateResult } from "./types.js";
import type { Variable, EvaluateResult } from "./../common/types.js";
import { ReferenceMap } from "./ReferenceMap.js";
import {
LexicalEnvironment,
@ -17,7 +17,7 @@ import {
DeclarativeEnvironmentRecord,
ObjectEnvironmentRecord,
GlobalEnvironmentRecord,
} from "./../environment.js";
} from "./../../environment.js";
import {
Value,
ConcreteValue,
@ -26,12 +26,14 @@ import {
AbstractObjectValue,
AbstractValue,
StringValue,
} from "./../values/index.js";
import invariant from "./../invariant.js";
import type { Realm } from "./../realm.js";
import { IsDataDescriptor } from "./../methods/is.js";
import { DebuggerError } from "./DebuggerError.js";
import { Functions } from "./../singletons.js";
} from "./../../values/index.js";
import invariant from "./../common/invariant.js";
import type { Realm } from "./../../realm.js";
import { IsDataDescriptor } from "./../../methods/is.js";
import { DebuggerError } from "./../common/DebuggerError.js";
import { Functions } from "./../../singletons.js";
type VariableContainer = LexicalEnvironment | ObjectValue | AbstractValue;
// This class manages the handling of variable requests in the debugger
// The DebugProtocol specifies collections of variables are to be fetched using a

View File

@ -8,10 +8,10 @@
*/
/* @flow */
import invariant from "./../../invariant.js";
import { FileIOWrapper } from "./FileIOWrapper.js";
import { DebugMessage } from "./DebugMessage.js";
import { MessageMarshaller } from "./MessageMarshaller.js";
import invariant from "./../../common/invariant.js";
import { FileIOWrapper } from "./../../common/channel/FileIOWrapper.js";
import { DebugMessage } from "./../../common/channel/DebugMessage.js";
import { MessageMarshaller } from "./../../common/channel/MessageMarshaller.js";
import type {
DebuggerRequest,
BreakpointsArguments,
@ -20,7 +20,7 @@ import type {
Variable,
StoppedReason,
EvaluateResult,
} from "./../types.js";
} from "./../../common/types.js";
//Channel used by the DebugServer in Prepack to communicate with the debug adapter
export class DebugChannel {

View File

@ -18,8 +18,8 @@ import { getDebuggerOptions } from "./prepack-options";
import { prepackNodeCLI, prepackNodeCLISync } from "./prepack-node-environment.js";
import { prepackSources } from "./prepack-standalone.js";
import { type SourceMap } from "./types.js";
import { DebugChannel } from "./debugger/channel/DebugChannel.js";
import { FileIOWrapper } from "./debugger/channel/FileIOWrapper.js";
import { DebugChannel } from "./debugger/server/channel/DebugChannel.js";
import { FileIOWrapper } from "./debugger/common/channel/FileIOWrapper.js";
import fs from "fs";

View File

@ -24,8 +24,8 @@ import type { PrepackOptions } from "./prepack-options";
import { defaultOptions } from "./options";
import type { BabelNodeFile, BabelNodeProgram } from "babel-types";
import invariant from "./invariant.js";
import type { DebugChannel } from "./debugger/channel/DebugChannel.js";
import { version } from "../package.json";
import type { DebugChannel } from "./debugger/server/channel/DebugChannel.js";
// IMPORTANT: This function is now deprecated and will go away in a future release.
// Please use FatalError instead.