UNPKG

atom-nuclide

Version:

A unified developer experience for web and mobile development, built as a suite of features on top of Atom to provide hackability and the support of an active community.

548 lines (504 loc) 19.1 kB
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { var callNext = step.bind(null, 'next'); var callThrow = step.bind(null, 'throw'); function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(callNext, callThrow); } } callNext(); }); }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } /* * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. */ var _commonsNodeNuclideUri2; function _commonsNodeNuclideUri() { return _commonsNodeNuclideUri2 = _interopRequireDefault(require('../../commons-node/nuclideUri')); } var _Constants2; function _Constants() { return _Constants2 = _interopRequireDefault(require('./Constants')); } var _atom2; function _atom() { return _atom2 = require('atom'); } var _AnalyticsHelper2; function _AnalyticsHelper() { return _AnalyticsHelper2 = require('./AnalyticsHelper'); } var _assert2; function _assert() { return _assert2 = _interopRequireDefault(require('assert')); } var _DebuggerStore2; function _DebuggerStore() { return _DebuggerStore2 = require('./DebuggerStore'); } var _commonsNodePassesGK2; function _commonsNodePassesGK() { return _commonsNodePassesGK2 = _interopRequireDefault(require('../../commons-node/passesGK')); } var _nuclideAnalytics2; function _nuclideAnalytics() { return _nuclideAnalytics2 = require('../../nuclide-analytics'); } var _nuclideLogging2; function _nuclideLogging() { return _nuclideLogging2 = require('../../nuclide-logging'); } var _commonsNodeString2; function _commonsNodeString() { return _commonsNodeString2 = require('../../commons-node/string'); } var logger = (0, (_nuclideLogging2 || _nuclideLogging()).getLogger)(); var AnalyticsEvents = Object.freeze({ DEBUGGER_START: 'debugger-start', DEBUGGER_START_FAIL: 'debugger-start-fail', DEBUGGER_STOP: 'debugger-stop' }); var GK_DEBUGGER_THREADS_WINDOW = 'nuclide_debugger_threads_window'; var GK_DEBUGGER_CONSOLE_WINDOW = 'nuclide_debugger_console_window'; var GK_DEBUGGER_SINGLE_THREAD_STEPPING = 'nuclide_debugger_single_thread_stepping'; /** * Flux style action creator for actions that affect the debugger. */ var DebuggerActions = (function () { function DebuggerActions(dispatcher, store) { _classCallCheck(this, DebuggerActions); this._disposables = new (_atom2 || _atom()).CompositeDisposable(); this._dispatcher = dispatcher; this._store = store; } _createClass(DebuggerActions, [{ key: 'startDebugging', value: _asyncToGenerator(function* (processInfo) { (0, (_nuclideAnalytics2 || _nuclideAnalytics()).track)(AnalyticsEvents.DEBUGGER_START, { serviceName: processInfo.getServiceName() }); (0, (_AnalyticsHelper2 || _AnalyticsHelper()).beginTimerTracking)('nuclide-debugger-atom:startDebugging'); this.stopDebugging(); // stop existing session. this.setError(null); this._handleDebugModeStart(); this.setDebuggerMode((_DebuggerStore2 || _DebuggerStore()).DebuggerMode.STARTING); try { atom.commands.dispatch(atom.views.getView(atom.workspace), 'nuclide-debugger:show'); var debuggerInstance = yield processInfo.debug(); if (yield (0, (_commonsNodePassesGK2 || _commonsNodePassesGK()).default)(GK_DEBUGGER_CONSOLE_WINDOW)) { this._registerConsole(); } var supportThreadsWindow = processInfo.supportThreads() && (yield (0, (_commonsNodePassesGK2 || _commonsNodePassesGK()).default)(GK_DEBUGGER_THREADS_WINDOW)); this._store.getSettings().set('SupportThreadsWindow', supportThreadsWindow); var singleThreadStepping = processInfo.supportSingleThreadStepping(); if (singleThreadStepping && (yield (0, (_commonsNodePassesGK2 || _commonsNodePassesGK()).default)(GK_DEBUGGER_SINGLE_THREAD_STEPPING))) { this._store.getSettings().set('SingleThreadStepping', singleThreadStepping); var singleThreadSteppingEnabled = processInfo.singleThreadSteppingEnabled(); this.toggleSingleThreadStepping(singleThreadSteppingEnabled); } yield this._waitForChromeConnection(debuggerInstance); } catch (err) { (0, (_AnalyticsHelper2 || _AnalyticsHelper()).failTimerTracking)(err); (0, (_nuclideAnalytics2 || _nuclideAnalytics()).track)(AnalyticsEvents.DEBUGGER_START_FAIL, {}); var errorMessage = 'Failed to start debugger process: ' + (0, (_commonsNodeString2 || _commonsNodeString()).stringifyError)(err); this.setError(errorMessage); atom.notifications.addError(errorMessage); this.stopDebugging(); } }) }, { key: 'setDebuggerMode', value: function setDebuggerMode(debuggerMode) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.DEBUGGER_MODE_CHANGE, data: debuggerMode }); } }, { key: '_waitForChromeConnection', value: _asyncToGenerator(function* (debuggerInstance) { this._setDebuggerInstance(debuggerInstance); if (debuggerInstance.onSessionEnd != null) { var handler = this._handleSessionEnd.bind(this, debuggerInstance); (0, (_assert2 || _assert()).default)(debuggerInstance.onSessionEnd); this._disposables.add(debuggerInstance.onSessionEnd(handler)); } var socketAddr = yield debuggerInstance.getWebsocketAddress(); (0, (_AnalyticsHelper2 || _AnalyticsHelper()).endTimerTracking)(); this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.SET_PROCESS_SOCKET, data: socketAddr }); // Debugger finished initializing and entered debug mode. this.setDebuggerMode((_DebuggerStore2 || _DebuggerStore()).DebuggerMode.RUNNING); // Wait for 'resume' event from Bridge.js to guarantee we've passed the loader breakpoint. yield this._store.loaderBreakpointResumePromise; }) }, { key: '_setDebuggerInstance', value: function _setDebuggerInstance(debuggerInstance) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.SET_DEBUGGER_INSTANCE, data: debuggerInstance }); } }, { key: '_handleSessionEnd', value: function _handleSessionEnd(debuggerInstance) { if (this._store.getDebuggerInstance() === debuggerInstance) { this.stopDebugging(); } else { // Do nothing, because either: // 1. Another DebuggerInstnace is alive. or // 2. DebuggerInstance has been disposed. } } }, { key: 'stopDebugging', value: function stopDebugging() { if (this._store.getDebuggerMode() === (_DebuggerStore2 || _DebuggerStore()).DebuggerMode.STOPPING) { return; } this.setDebuggerMode((_DebuggerStore2 || _DebuggerStore()).DebuggerMode.STOPPING); this._unregisterConsole(); var debuggerInstance = this._store.getDebuggerInstance(); if (debuggerInstance != null) { debuggerInstance.dispose(); this._setDebuggerInstance(null); } this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.SET_PROCESS_SOCKET, data: null }); this.setDebuggerMode((_DebuggerStore2 || _DebuggerStore()).DebuggerMode.STOPPED); (0, (_nuclideAnalytics2 || _nuclideAnalytics()).track)(AnalyticsEvents.DEBUGGER_STOP); (0, (_AnalyticsHelper2 || _AnalyticsHelper()).endTimerTracking)(); (0, (_assert2 || _assert()).default)(this._store.getDebuggerInstance() === null); atom.commands.dispatch(atom.views.getView(atom.workspace), 'nuclide-debugger:hide'); } }, { key: '_registerConsole', value: function _registerConsole() { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.REGISTER_CONSOLE }); } }, { key: '_unregisterConsole', value: function _unregisterConsole() { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.UNREGISTER_CONSOLE }); } }, { key: 'addConsoleRegisterFunction', value: function addConsoleRegisterFunction(registerExecutor) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.ADD_REGISTER_EXECUTOR, data: registerExecutor }); } }, { key: 'removeConsoleRegisterFunction', value: function removeConsoleRegisterFunction(registerExecutor) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.REMOVE_REGISTER_EXECUTOR, data: registerExecutor }); } }, { key: 'addDebuggerProvider', value: function addDebuggerProvider(provider) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.ADD_DEBUGGER_PROVIDER, data: provider }); } }, { key: 'removeDebuggerProvider', value: function removeDebuggerProvider(provider) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.REMOVE_DEBUGGER_PROVIDER, data: provider }); } }, { key: 'addEvaluationExpressionProvider', value: function addEvaluationExpressionProvider(provider) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.ADD_EVALUATION_EXPRESSION_PROVIDER, data: provider }); } }, { key: 'removeEvaluationExpressionProvider', value: function removeEvaluationExpressionProvider(provider) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.REMOVE_EVALUATION_EXPRESSION_PROVIDER, data: provider }); } }, { key: 'setError', value: function setError(error) { if (error != null) { logger.error(error); } this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.SET_ERROR, data: error }); } /** * Utility for debugging. * * This can be used to set an existing socket, bypassing normal UI flow to * improve iteration speed for development. */ }, { key: 'forceProcessSocket', value: function forceProcessSocket(socketAddr) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.SET_PROCESS_SOCKET, data: socketAddr }); } /** * Utility for getting refreshed connections. * TODO: refresh connections when new directories are removed/added in file-tree. */ }, { key: 'updateConnections', value: function updateConnections() { var connections = this._getRemoteConnections(); // Always have one single local connection. connections.push('local'); this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.UPDATE_CONNECTIONS, data: connections }); } /** * Get remote connections without duplication. */ }, { key: '_getRemoteConnections', value: function _getRemoteConnections() { // TODO: move this logic into RemoteConnection package. return atom.project.getPaths().filter(function (path) { return (_commonsNodeNuclideUri2 || _commonsNodeNuclideUri()).default.isRemote(path); }).map(function (remotePath) { var _default$parseRemoteUri = (_commonsNodeNuclideUri2 || _commonsNodeNuclideUri()).default.parseRemoteUri(remotePath); var hostname = _default$parseRemoteUri.hostname; return (_commonsNodeNuclideUri2 || _commonsNodeNuclideUri()).default.createRemoteUri(hostname, '/'); }).filter(function (path, index, inputArray) { return inputArray.indexOf(path) === index; }); } }, { key: 'addWatchExpression', value: function addWatchExpression(expression) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.ADD_WATCH_EXPRESSION, data: { expression: expression } }); } }, { key: 'removeWatchExpression', value: function removeWatchExpression(index) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.REMOVE_WATCH_EXPRESSION, data: { index: index } }); } }, { key: 'updateWatchExpression', value: function updateWatchExpression(index, newExpression) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.UPDATE_WATCH_EXPRESSION, data: { newExpression: newExpression, index: index } }); } }, { key: 'openSourceLocation', value: function openSourceLocation(sourceURL, lineNumber) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.OPEN_SOURCE_LOCATION, data: { sourceURL: sourceURL, lineNumber: lineNumber } }); } /** * `actionId` is a debugger action understood by Chrome's `WebInspector.ActionRegistry`. */ }, { key: 'triggerDebuggerAction', value: function triggerDebuggerAction(actionId) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.TRIGGER_DEBUGGER_ACTION, data: { actionId: actionId } }); } }, { key: 'updateCallstack', value: function updateCallstack(callstack) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.UPDATE_CALLSTACK, data: { callstack: callstack } }); } }, { key: 'setSelectedCallFrameline', value: function setSelectedCallFrameline(options) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.SET_SELECTED_CALLFRAME_LINE, data: { options: options } }); } }, { key: 'clearInterface', value: function clearInterface() { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.CLEAR_INTERFACE, data: {} }); } }, { key: 'addBreakpoint', value: function addBreakpoint(path, line) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.ADD_BREAKPOINT, data: { path: path, line: line } }); } }, { key: 'deleteBreakpoint', value: function deleteBreakpoint(path, line) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.DELETE_BREAKPOINT, data: { path: path, line: line } }); } }, { key: 'toggleBreakpoint', value: function toggleBreakpoint(path, line) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.TOGGLE_BREAKPOINT, data: { path: path, line: line } }); } }, { key: 'deleteBreakpointIPC', value: function deleteBreakpointIPC(path, line) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.DELETE_BREAKPOINT_IPC, data: { path: path, line: line } }); } }, { key: 'bindBreakpointIPC', value: function bindBreakpointIPC(path, line) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.BIND_BREAKPOINT_IPC, data: { path: path, line: line } }); } }, { key: 'togglePauseOnException', value: function togglePauseOnException(pauseOnException) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.TOGGLE_PAUSE_ON_EXCEPTION, data: pauseOnException }); } }, { key: 'togglePauseOnCaughtException', value: function togglePauseOnCaughtException(pauseOnCaughtException) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.TOGGLE_PAUSE_ON_CAUGHT_EXCEPTION, data: pauseOnCaughtException }); } }, { key: 'toggleSingleThreadStepping', value: function toggleSingleThreadStepping(singleThreadStepping) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.TOGGLE_SINGLE_THREAD_STEPPING, data: singleThreadStepping }); } }, { key: 'updateLocals', value: function updateLocals(locals) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.UPDATE_LOCALS, data: { locals: locals } }); } }, { key: 'dispose', value: function dispose() { (0, (_AnalyticsHelper2 || _AnalyticsHelper()).endTimerTracking)(); this._disposables.dispose(); } }, { key: 'updateThreads', value: function updateThreads(threadData) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.UPDATE_THREADS, data: { threadData: threadData } }); } }, { key: 'notifyThreadSwitch', value: function notifyThreadSwitch(sourceURL, lineNumber, message) { this._dispatcher.dispatch({ actionType: (_Constants2 || _Constants()).default.Actions.NOTIFY_THREAD_SWITCH, data: { sourceURL: sourceURL, lineNumber: lineNumber, message: message } }); } }, { key: '_handleDebugModeStart', value: function _handleDebugModeStart() { // Open the console window if it's not already opened. atom.commands.dispatch(atom.views.getView(atom.workspace), 'nuclide-console:toggle', { visible: true }); } }]); return DebuggerActions; })(); module.exports = DebuggerActions;