diff --git a/DEVELOPMENT b/DEVELOPMENT deleted file mode 100644 index e69de29b..00000000 diff --git a/flow-libs/nuclide.flow.js b/flow-libs/nuclide.flow.js index 348f646b..9a390c31 100644 --- a/flow-libs/nuclide.flow.js +++ b/flow-libs/nuclide.flow.js @@ -1,22 +1 @@ -/** - * 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. - * - * @flow - * @format - */ - -/* eslint-disable no-undef */ - -declare interface nuclide$CwdApi { - setCwd(path: string): void; - observeCwd(callback: (path: ?string) => void): IDisposable; - getCwd(): ?string; -} - -declare interface nuclide$RpcService { - getServiceByNuclideUri(serviceName: string, uri: ?string): any; -} +"use strict"; \ No newline at end of file diff --git a/index.js b/index.js index 951b2196..331725bf 100644 --- a/index.js +++ b/index.js @@ -1,70 +1,70 @@ -/** - * 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 - * @format - */ - -/* eslint-disable rulesdir/no-commonjs */ - -import fs from 'fs'; -// eslint-disable-next-line rulesdir/prefer-nuclide-uri -import path from 'path'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import FeatureLoader from 'nuclide-commons-atom/FeatureLoader'; -import displayNuclideWarning from './display-nuclide-warning'; - -const featureDir = path.join(__dirname, 'modules/atom-ide-ui/pkg'); -const features = fs - .readdirSync(featureDir) - .map(item => { - const dirname = path.join(featureDir, item); - try { - const pkgJson = fs.readFileSync( - path.join(dirname, 'package.json'), - 'utf8', - ); - return { - path: dirname, - pkg: JSON.parse(pkgJson), - }; - } catch (err) { - if (err.code !== 'ENOENT' && err.code !== 'ENOTDIR') { - throw err; - } +'use strict'; + + + + + + + + + + + + + +var _fs = _interopRequireDefault(require('fs')); + +var _path = _interopRequireDefault(require('path'));var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _FeatureLoader; +function _load_FeatureLoader() {return _FeatureLoader = _interopRequireDefault(require('nuclide-commons-atom/FeatureLoader'));}var _displayNuclideWarning; +function _load_displayNuclideWarning() {return _displayNuclideWarning = _interopRequireDefault(require('./display-nuclide-warning'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} // eslint-disable-next-line rulesdir/prefer-nuclide-uri + +const featureDir = _path.default.join(__dirname, 'modules/atom-ide-ui/pkg'); /** + * 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. + * + * + * @format + */ /* eslint-disable rulesdir/no-commonjs */const features = _fs.default.readdirSync(featureDir).map(item => {const dirname = _path.default.join(featureDir, item);try {const pkgJson = _fs.default.readFileSync(_path.default.join(dirname, 'package.json'), 'utf8');return { + path: dirname, + pkg: JSON.parse(pkgJson) }; + + } catch (err) { + if (err.code !== 'ENOENT' && err.code !== 'ENOTDIR') { + throw err; } - }) - .filter(Boolean); + } +}). +filter(Boolean); /** - * Use a unified package loader to load all the feature packages. - * See the following post for more context: - * https://nuclide.io/blog/2016/01/13/Nuclide-v0.111.0-The-Unified-Package/ - */ -let disposables: ?UniversalDisposable; -const featureLoader = new FeatureLoader({ + * Use a unified package loader to load all the feature packages. + * See the following post for more context: + * https://nuclide.io/blog/2016/01/13/Nuclide-v0.111.0-The-Unified-Package/ + */ +let disposables; +const featureLoader = new (_FeatureLoader || _load_FeatureLoader()).default({ path: __dirname, config: {}, - features, -}); + features }); + featureLoader.load(); module.exports = { config: featureLoader.getConfig(), activate() { - disposables = new UniversalDisposable( - require('nuclide-commons-ui'), - atom.packages.onDidActivatePackage(pkg => { - if (pkg.name === 'nuclide') { - displayNuclideWarning(); - } - }), - ); + disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default( + require('nuclide-commons-ui'), + atom.packages.onDidActivatePackage(pkg => { + if (pkg.name === 'nuclide') { + (0, (_displayNuclideWarning || _load_displayNuclideWarning()).default)(); + } + })); + featureLoader.activate(); }, deactivate() { @@ -76,5 +76,4 @@ module.exports = { }, serialize() { featureLoader.serialize(); - }, -}; + } }; \ No newline at end of file diff --git a/modules/atom-ide-ui/index.js b/modules/atom-ide-ui/index.js index 8895e7ee..3a4e236b 100644 --- a/modules/atom-ide-ui/index.js +++ b/modules/atom-ide-ui/index.js @@ -1,127 +1,116 @@ -/** - * 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 - * @format - */ - -export type { - BusySignalOptions, - BusySignalService, -} from './pkg/atom-ide-busy-signal/lib/types'; - -export type { - CodeAction, - CodeActionProvider, -} from './pkg/atom-ide-code-actions/lib/types'; - -export type { - CodeFormatProvider, - RangeCodeFormatProvider, - FileCodeFormatProvider, - OnTypeCodeFormatProvider, - OnSaveCodeFormatProvider, -} from './pkg/atom-ide-code-format/lib/types'; - -export type { - CodeHighlightProvider, -} from './pkg/atom-ide-code-highlight/lib/types'; - -export type { - Datatip, - DatatipProvider, - DatatipService, - MarkedString, - ModifierDatatipProvider, - ModifierKey, -} from './pkg/atom-ide-datatip/lib/types'; - -export type { - Definition, - DefinitionProvider, - DefinitionPreviewProvider, - DefinitionQueryResult, -} from './pkg/atom-ide-definitions/lib/types'; - -export type { - CallbackDiagnosticProvider, - DiagnosticFix, - DiagnosticInvalidationCallback, - DiagnosticInvalidationMessage, - DiagnosticMessage, - DiagnosticMessages, - DiagnosticMessageKind, - DiagnosticMessageType, - DiagnosticProvider, - DiagnosticProviderUpdate, - DiagnosticTrace, - DiagnosticUpdateCallback, - IndieLinterDelegate, - LinterMessage, - LinterMessageV1, - LinterMessageV2, - LinterProvider, - LinterTrace, - ObservableDiagnosticProvider, - RegisterIndieLinter, -} from './pkg/atom-ide-diagnostics/lib/types'; - -export type { - FindReferencesProvider, - FindReferencesReturn, - Reference, -} from './pkg/atom-ide-find-references/lib/types'; - -export type { - Outline, - OutlineProvider, - OutlineTree, - ResultsStreamProvider, -} from './pkg/atom-ide-outline-view/lib/types'; - -export type { - Signature, - SignatureHelp, - SignatureHelpProvider, - SignatureHelpRegistry, - SignatureParameter, -} from './pkg/atom-ide-signature-help/lib/types'; - -export type { - HyperclickProvider, - HyperclickSuggestion, -} from './pkg/hyperclick/lib/types'; - -export type { - ConsoleService, - ConsoleApi, - Level as ConsoleLevel, - Message as ConsoleMessage, - SourceInfo as ConsoleSourceInfo, - OutputProviderStatus, -} from './pkg/atom-ide-console/lib/types'; - -// Deprecated console types. Exported only for legacy users. -export type { - OutputService, - RegisterExecutorFunction, -} from './pkg/atom-ide-console/lib/types'; - -export { - default as DebuggerService, -} from './pkg/atom-ide-debugger/lib/RemoteControlService'; - -export type { - TerminalInfo, - TerminalInstance, - TerminalApi, -} from './pkg/atom-ide-terminal/lib/types'; - -export type { - Command as TerminalCommand, -} from './pkg/atom-ide-terminal/lib/pty-service/rpc-types'; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _RemoteControlService;function _load_RemoteControlService() {return _RemoteControlService = require('./pkg/atom-ide-debugger/lib/RemoteControlService');}Object.defineProperty(exports, 'DebuggerService', { enumerable: true, get: function () {return _interopRequireDefault(_RemoteControlService || _load_RemoteControlService()). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + default;} });function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/BusyMessageInstance.js b/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/BusyMessageInstance.js index cec5474a..69b596ad 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/BusyMessageInstance.js +++ b/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/BusyMessageInstance.js @@ -1,41 +1,41 @@ -/** - * 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 - * @format - */ +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.BusyMessageInstance = undefined;var _UniversalDisposable; + + + + + + + + + + + + + + +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +class BusyMessageInstance { + + + + -import type {BusyMessage} from './types'; -import invariant from 'assert'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -export class BusyMessageInstance { - // These things are set at construction-time: - _publishCallback: () => void; - _creationOrder: number; - _waitingFor: 'computer' | 'user'; - _onDidClick: ?() => void; - _disposables: UniversalDisposable; - _titleElement: HTMLElement = document.createElement('span'); // These things might be modified afterwards: - _currentTitle: ?string = null; - _isVisibleForDebounce: boolean = true; - _isVisibleForFile: boolean = true; - _revealTooltip: boolean = false; + // These things are set at construction-time: + + + constructor( - publishCallback: () => void, - creationOrder: number, - waitingFor: 'computer' | 'user', - onDidClick: ?() => void, - disposables: UniversalDisposable, - ) { + publishCallback, + creationOrder, + waitingFor, + onDidClick, + disposables) + {this._titleElement = document.createElement('span');this._currentTitle = null;this._isVisibleForDebounce = true;this._isVisibleForFile = true;this._revealTooltip = false; this._publishCallback = publishCallback; this._creationOrder = creationOrder; this._waitingFor = waitingFor; @@ -43,12 +43,12 @@ export class BusyMessageInstance { this._disposables = disposables; } - get waitingFor(): 'computer' | 'user' { + get waitingFor() { return this._waitingFor; } - setTitle(val: string): void { - invariant(!this._disposables.disposed); + setTitle(val) {if (! + !this._disposables.disposed) {throw new Error('Invariant violation: "!this._disposables.disposed"');} if (this._currentTitle === val) { return; } @@ -69,49 +69,59 @@ export class BusyMessageInstance { } } - getTitleElement(): ?HTMLElement { + getTitleElement() { return this._titleElement; } - setIsVisibleForDebounce(val: boolean): void { - invariant(!this._disposables.disposed); + setIsVisibleForDebounce(val) {if (! + !this._disposables.disposed) {throw new Error('Invariant violation: "!this._disposables.disposed"');} this._isVisibleForDebounce = val; this._publishCallback(); } - setIsVisibleForFile(val: boolean): void { - invariant(!this._disposables.disposed); + setIsVisibleForFile(val) {if (! + !this._disposables.disposed) {throw new Error('Invariant violation: "!this._disposables.disposed"');} this._isVisibleForFile = val; this._publishCallback(); } - isVisible(): boolean { - invariant(!this._disposables.disposed); + isVisible() {if (! + !this._disposables.disposed) {throw new Error('Invariant violation: "!this._disposables.disposed"');} return ( this._isVisibleForFile && this._isVisibleForDebounce && - this._currentTitle != null - ); + this._currentTitle != null); + } - setRevealTooltip(val: boolean): void { + setRevealTooltip(val) { this._revealTooltip = val; } - shouldRevealTooltip(): boolean { + shouldRevealTooltip() { return this._revealTooltip; } - compare(that: BusyMessageInstance): number { + compare(that) { return this._creationOrder - that._creationOrder; } - dispose(): void { + dispose() { this._disposables.dispose(); this._currentTitle = null; this._publishCallback(); - } -} + }}exports.BusyMessageInstance = BusyMessageInstance; + // This is how we declare that a type fulfills an interface in Flow: -(((null: any): BusyMessageInstance): BusyMessage); +/** + * 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. + * + * + * @format + */null; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/BusySignalSingleton.js b/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/BusySignalSingleton.js index a736a344..03cbf3eb 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/BusySignalSingleton.js +++ b/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/BusySignalSingleton.js @@ -1,48 +1,47 @@ -/** - * 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 - * @format - */ - -import type {BusySignalOptions, BusyMessage} from './types'; -import type {MessageStore} from './MessageStore'; - -export default class BusySignalSingleton { - _messageStore: MessageStore; - - constructor(messageStore: MessageStore) { +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */ + + + + +class BusySignalSingleton { + + + constructor(messageStore) { this._messageStore = messageStore; } dispose() {} - reportBusy(title: string, options?: BusySignalOptions): BusyMessage { + reportBusy(title, options) { return this._messageStore.add(title, options || {}); } /** - * Publishes a 'busy' message with the given string. Marks it as done when the - * promise returned by the given function is resolved or rejected. - * - * Used to indicate that some work is ongoing while the given asynchronous - * function executes. - */ - async reportBusyWhile( - title: string, - f: () => Promise, - options?: BusySignalOptions, - ): Promise { - const busySignal = this.reportBusy(title, options); - try { - return await f(); - } finally { - busySignal.dispose(); - } - } -} + * Publishes a 'busy' message with the given string. Marks it as done when the + * promise returned by the given function is resolved or rejected. + * + * Used to indicate that some work is ongoing while the given asynchronous + * function executes. + */ + reportBusyWhile( + title, + f, + options) + {var _this = this;return (0, _asyncToGenerator.default)(function* () { + const busySignal = _this.reportBusy(title, options); + try { + return yield f(); + } finally { + busySignal.dispose(); + }})(); + }}exports.default = BusySignalSingleton; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/MessageStore.js b/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/MessageStore.js index 7a54f563..3cbbdd01 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/MessageStore.js +++ b/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/MessageStore.js @@ -1,3 +1,27 @@ +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.MessageStore = undefined; + + + + + + + + + + + + + + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _collection; +function _load_collection() {return _collection = require('nuclide-commons/collection');}var _BusyMessageInstance; +function _load_BusyMessageInstance() {return _BusyMessageInstance = require('./BusyMessageInstance');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +// The "busy debounce delay" is for busy messages that were created with the +// 'debounce' option set to true. The icon and tooltip message won't appear +// until this many milliseconds have elapsed; if the busy message gets disposed +// before this time, then the user won't see anything. /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,94 +30,70 @@ * 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 + * * @format - */ - -import type {BusyMessage, BusySignalOptions} from './types'; - -import invariant from 'assert'; -import {Observable, BehaviorSubject} from 'rxjs'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {arrayEqual} from 'nuclide-commons/collection'; -import {BusyMessageInstance} from './BusyMessageInstance'; - -// The "busy debounce delay" is for busy messages that were created with the -// 'debounce' option set to true. The icon and tooltip message won't appear -// until this many milliseconds have elapsed; if the busy message gets disposed -// before this time, then the user won't see anything. -const BUSY_DEBOUNCE_DELAY = 300; - -export class MessageStore { - _counter: number = 0; - _messages: Set = new Set(); - _currentVisibleMessages: Array = []; - _messageStream: BehaviorSubject< - Array, - > = new BehaviorSubject([]); - - getMessageStream(): Observable> { + */const BUSY_DEBOUNCE_DELAY = 300;class MessageStore {constructor() {this._counter = 0;this._messages = new Set();this._currentVisibleMessages = [];this._messageStream = new _rxjsBundlesRxMinJs.BehaviorSubject([]);}getMessageStream() { return this._messageStream; } - dispose(): void { + dispose() { const messagesToDispose = [...this._messages]; for (const message of messagesToDispose) { message.dispose(); - } - invariant(this._messages.size === 0); + }if (!( + this._messages.size === 0)) {throw new Error('Invariant violation: "this._messages.size === 0"');} this._messageStream.complete(); } - _publish(): void { - const visibleMessages = [...this._messages] - .filter(m => m.isVisible()) - .sort((m1, m2) => m1.compare(m2)); + _publish() { + const visibleMessages = [...this._messages]. + filter(m => m.isVisible()). + sort((m1, m2) => m1.compare(m2)); // We only send out on messageStream when the list of visible // BusyMessageInstance object identities has changed, e.g. when ones // are made visible or invisible or new ones are created. We don't send // out just on title change. - if (!arrayEqual(this._currentVisibleMessages, visibleMessages)) { + if (!(0, (_collection || _load_collection()).arrayEqual)(this._currentVisibleMessages, visibleMessages)) { this._messageStream.next(visibleMessages); this._currentVisibleMessages = visibleMessages; } } - add(title: string, options: BusySignalOptions): BusyMessage { + add(title, options) { this._counter++; const creationOrder = this._counter; const waitingFor = - options != null && options.waitingFor != null - ? options.waitingFor - : 'computer'; + options != null && options.waitingFor != null ? + options.waitingFor : + 'computer'; const onDidClick = options == null ? null : options.onDidClick; - const messageDisposables = new UniversalDisposable(); - - const message = new BusyMessageInstance( - this._publish.bind(this), - creationOrder, - waitingFor, - onDidClick, - messageDisposables, - ); + const messageDisposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + + const message = new (_BusyMessageInstance || _load_BusyMessageInstance()).BusyMessageInstance( + this._publish.bind(this), + creationOrder, + waitingFor, + onDidClick, + messageDisposables); + this._messages.add(message); messageDisposables.add(() => this._messages.delete(message)); // debounce defaults 'true' for busy-signal, and 'false' for action-required - const debounceRaw: ?boolean = options == null ? null : options.debounce; - const debounce: boolean = - debounceRaw == null ? waitingFor === 'computer' : debounceRaw; + const debounceRaw = options == null ? null : options.debounce; + const debounce = + debounceRaw == null ? waitingFor === 'computer' : debounceRaw; if (debounce) { message.setIsVisibleForDebounce(false); // After the debounce time, we'll check whether the messageId is still // around (i.e. hasn't yet been disposed), and if so we'll display it. - let timeoutId = ((0: any): TimeoutID); + let timeoutId = 0; const teardown = () => clearTimeout(timeoutId); - timeoutId = setTimeout(() => { - invariant(!messageDisposables.disposed); - invariant(this._messages.has(message)); + timeoutId = setTimeout(() => {if (! + !messageDisposables.disposed) {throw new Error('Invariant violation: "!messageDisposables.disposed"');}if (! + this._messages.has(message)) {throw new Error('Invariant violation: "this._messages.has(message)"');} // If the message was disposed, then it should have already called // clearTimeout, so this timeout handler shouldn't have been invoked. // And also the message should have been removed from this._messages. @@ -111,9 +111,9 @@ export class MessageStore { const file = options.onlyForFile; const teardown = atom.workspace.observeActivePaneItem(item => { const activePane = - item != null && typeof item.getPath === 'function' - ? String(item.getPath()) - : null; + item != null && typeof item.getPath === 'function' ? + String(item.getPath()) : + null; const newVisible = activePane === file; message.setIsVisibleForFile(newVisible); }); @@ -131,5 +131,4 @@ export class MessageStore { // and then when the title is set, it will display or not as appropriate. return message; - } -} + }}exports.MessageStore = MessageStore; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/StatusBarTile.js b/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/StatusBarTile.js index 5c5aafc5..f94fc4c2 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/StatusBarTile.js +++ b/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/StatusBarTile.js @@ -1,3 +1,27 @@ +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); + + + + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react')); +var _reactDom = _interopRequireDefault(require('react-dom'));var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _collection; +function _load_collection() {return _collection = require('nuclide-commons/collection');}var _Icon; +function _load_Icon() {return _Icon = require('nuclide-commons-ui/Icon');}var _BusyMessageInstance; +function _load_BusyMessageInstance() {return _BusyMessageInstance = require('./BusyMessageInstance');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} + +// We want to be the furthest left on the right side of the status bar so as not to leave a +// conspicuous gap (or cause jitter) when nothing is busy. /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,70 +30,46 @@ * 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 + * * @format - */ - -import type {Observable} from 'rxjs'; - -import invariant from 'assert'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {arrayCompact} from 'nuclide-commons/collection'; -import {Icon} from 'nuclide-commons-ui/Icon'; -import {BusyMessageInstance} from './BusyMessageInstance'; - -// We want to be the furthest left on the right side of the status bar so as not to leave a -// conspicuous gap (or cause jitter) when nothing is busy. -const STATUS_BAR_PRIORITY = 1000; - -type Props = { - waitingForComputer: boolean, - waitingForUser: boolean, - onDidClick: ?() => void, -}; - -function StatusBarTileComponent(props: Props) { - let element; - if (props.waitingForUser) { - element = ; + */const STATUS_BAR_PRIORITY = 1000;function StatusBarTileComponent(props) {let element;if (props.waitingForUser) { + element = _react.createElement((_Icon || _load_Icon()).Icon, { className: 'busy-signal-status-bar', icon: 'unverified' }); } else if (props.waitingForComputer) { - element =
; + element = _react.createElement('div', { className: 'busy-signal-status-bar loading-spinner-tiny' }); } else { element = null; } if (props.onDidClick != null) { - element = {element}; + element = _react.createElement('a', { onClick: props.onDidClick }, element); } return element; } -export default class StatusBarTile { - _item: HTMLElement; - _tile: atom$StatusBarTile; - _tooltip: ?IDisposable; - _disposables: UniversalDisposable; - _messages: Array = []; - _isMouseOverItem: boolean = false; - _isMouseOverTooltip: number = 0; - _leaveTimeoutId: ?TimeoutID; +class StatusBarTile { + + + + + + + + constructor( - statusBar: atom$StatusBar, - messageStream: Observable>, - ) { + statusBar, + messageStream) + {this._messages = [];this._isMouseOverItem = false;this._isMouseOverTooltip = 0; this._item = document.createElement('div'); this._tile = this._createTile(statusBar); - this._disposables = new UniversalDisposable( - messageStream.subscribe(messages => this._handleMessages(messages)), - ); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default( + messageStream.subscribe(messages => this._handleMessages(messages))); + } - dispose(): void { - ReactDOM.unmountComponentAtNode(this._item); + dispose() { + _reactDom.default.unmountComponentAtNode(this._item); this._tile.destroy(); if (this._tooltip != null) { this._tooltip.dispose(); @@ -77,7 +77,7 @@ export default class StatusBarTile { this._disposables.dispose(); } - _createTile(statusBar: atom$StatusBar): atom$StatusBarTile { + _createTile(statusBar) { const item = this._item; item.className = 'inline-block'; item.addEventListener('mouseenter', () => { @@ -91,29 +91,29 @@ export default class StatusBarTile { }); const tile = statusBar.addRightTile({ item, - priority: STATUS_BAR_PRIORITY, - }); + priority: STATUS_BAR_PRIORITY }); + return tile; } - _handleMessages(messages: Array): void { + _handleMessages(messages) { this._messages = messages; - const onDidClicks = arrayCompact(messages.map(m => m._onDidClick)); + const onDidClicks = (0, (_collection || _load_collection()).arrayCompact)(messages.map(m => m._onDidClick)); - const props: Props = { + const props = { waitingForComputer: messages.some(m => m.waitingFor === 'computer'), waitingForUser: messages.some(m => m.waitingFor === 'user'), onDidClick: - onDidClicks.length > 0 - ? () => onDidClicks.forEach(callback => callback()) - : null, - }; - ReactDOM.render(, this._item); + onDidClicks.length > 0 ? + () => onDidClicks.forEach(callback => callback()) : + null }; + + _reactDom.default.render(_react.createElement(StatusBarTileComponent, props), this._item); const revealTooltip = messages.some(message => - message.shouldRevealTooltip(), - ); + message.shouldRevealTooltip()); + if (this._tooltip != null) { // If the user already had the tooltip up, then we'll either // refresh it or hide it. No matter what, we'll have to unmount it. @@ -122,9 +122,9 @@ export default class StatusBarTile { // 1) the mouse was previously over the tile or the tooltip // 2) one of the messages is marked with 'reveal tooltip' if ( - messages.length > 0 && - (revealTooltip || this._isMouseOverItem || this._isMouseOverTooltip) - ) { + messages.length > 0 && ( + revealTooltip || this._isMouseOverItem || this._isMouseOverTooltip)) + { this._ensureTooltip(); } else { this._isMouseOverItem = false; @@ -134,7 +134,7 @@ export default class StatusBarTile { } } - _disposeTooltip(): void { + _disposeTooltip() { if (this._tooltip != null) { this._tooltip.dispose(); this._tooltip = null; @@ -142,7 +142,7 @@ export default class StatusBarTile { } } - _ensureTooltip(): void { + _ensureTooltip() { if (this._tooltip != null) { return; } @@ -151,16 +151,16 @@ export default class StatusBarTile { if (body.childElementCount > 0) { body.appendChild(document.createElement('br')); } - const titleElement = message.getTitleElement(); - invariant(titleElement != null); + const titleElement = message.getTitleElement();if (!( + titleElement != null)) {throw new Error('Invariant violation: "titleElement != null"');} body.appendChild(titleElement); } this._tooltip = atom.tooltips.add(this._item, { item: body, delay: 0, - trigger: 'manual', - }); + trigger: 'manual' }); + const tooltipAtomObjects = atom.tooltips.tooltips.get(this._item); if (tooltipAtomObjects != null) { for (const tooltipAtomObject of tooltipAtomObjects) { @@ -177,12 +177,12 @@ export default class StatusBarTile { } } - _startLeaveTimeoutIfNecessary(): void { + _startLeaveTimeoutIfNecessary() { if ( - !this._isMouseOverItem && - this._isMouseOverTooltip === 0 && - this._leaveTimeoutId == null - ) { + !this._isMouseOverItem && + this._isMouseOverTooltip === 0 && + this._leaveTimeoutId == null) + { this._leaveTimeoutId = setTimeout(() => { this._disposeTooltip(); // Currently visible messages should no longer reveal the tooltip again. @@ -191,10 +191,9 @@ export default class StatusBarTile { } } - _stopLeaveTimeout(): void { + _stopLeaveTimeout() { if (this._leaveTimeoutId != null) { clearTimeout(this._leaveTimeoutId); this._leaveTimeoutId = null; } - } -} + }}exports.default = StatusBarTile; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/main.js b/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/main.js index 0dadbe3e..24e77443 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/main.js +++ b/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/main.js @@ -1,50 +1,50 @@ -/** - * 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 - * @format - */ - -import type {BusySignalService} from './types'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import BusySignalSingleton from './BusySignalSingleton'; -import {MessageStore} from './MessageStore'; -import StatusBarTile from './StatusBarTile'; - -class Activation { - _disposables: UniversalDisposable; - _service: BusySignalService; - _messageStore: MessageStore; - - constructor() { - this._messageStore = new MessageStore(); - this._service = new BusySignalSingleton(this._messageStore); - this._disposables = new UniversalDisposable(this._messageStore); +'use strict';var _createPackage; + + + + + + + + + + + + + +function _load_createPackage() {return _createPackage = _interopRequireDefault(require('nuclide-commons-atom/createPackage'));}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _BusySignalSingleton; +function _load_BusySignalSingleton() {return _BusySignalSingleton = _interopRequireDefault(require('./BusySignalSingleton'));}var _MessageStore; +function _load_MessageStore() {return _MessageStore = require('./MessageStore');}var _StatusBarTile; +function _load_StatusBarTile() {return _StatusBarTile = _interopRequireDefault(require('./StatusBarTile'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */class Activation {constructor() {this._messageStore = new (_MessageStore || _load_MessageStore()).MessageStore();this._service = new (_BusySignalSingleton || _load_BusySignalSingleton()).default(this._messageStore);this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(this._messageStore); } dispose() { this._disposables.dispose(); } - consumeStatusBar(statusBar: atom$StatusBar): IDisposable { + consumeStatusBar(statusBar) { // Avoid retaining StatusBarTile by wrapping it. - const disposable = new UniversalDisposable( - new StatusBarTile(statusBar, this._messageStore.getMessageStream()), - ); + const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default( + new (_StatusBarTile || _load_StatusBarTile()).default(statusBar, this._messageStore.getMessageStream())); + this._disposables.add(disposable); return disposable; } - provideBusySignal(): BusySignalService { + provideBusySignal() { return this._service; - } -} + }} + -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/types.js b/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/types.js index 38a0a1cd..a726efc4 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/types.js +++ b/modules/atom-ide-ui/pkg/atom-ide-busy-signal/lib/types.js @@ -1,57 +1 @@ -/** - * 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 - * @format - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -export type BusySignalOptions = {| - // Can say that a busy signal will only appear when a given file is open. - // Default = null, meaning the busy signal applies to all files. - onlyForFile?: NuclideUri, - // Is user waiting for computer to finish a task? (traditional busy spinner) - // or is the computer waiting for user to finish a task? (action required) - // Default = spinner. - waitingFor?: 'computer' | 'user', - // Debounce it? default = true for busy-signal, and false for action-required. - debounce?: boolean, - // If onClick is set, then the tooltip will be clickable. Default = null. - onDidClick?: () => void, - // If set to true, the busy signal tooltip will be immediately revealed - // when it first becomes visible (without explicit mouse interaction). - revealTooltip?: boolean, -|}; - -export type BusySignalService = { - // Activates the busy signal with the given title and returns the promise - // from the provided callback. - // The busy signal automatically deactivates when the returned promise - // either resolves or rejects. - reportBusyWhile( - title: string, - f: () => Promise, - options?: BusySignalOptions, - ): Promise, - - // Activates the busy signal. Set the title in the returned BusySignal - // object (you can update the title multiple times) and dispose it when done. - reportBusy(title: string, options?: BusySignalOptions): BusyMessage, - - // This is a no-op. When someone consumes the busy service, they get back a - // reference to the single shared instance, so disposing of it would be wrong. - dispose(): void, -}; - -export type BusyMessage = { - // You can set/update the title. - setTitle(title: string): void, - // Dispose of the signal when done to make it go away. - dispose(): void, -}; +'use strict'; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-busy-signal/spec/BusySignalInstance-spec.js b/modules/atom-ide-ui/pkg/atom-ide-busy-signal/spec/BusySignalInstance-spec.js index ca086019..0ce483a8 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-busy-signal/spec/BusySignalInstance-spec.js +++ b/modules/atom-ide-ui/pkg/atom-ide-busy-signal/spec/BusySignalInstance-spec.js @@ -1,47 +1,47 @@ -/** - * 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 - * @format - */ - -import type {BusySignalOptions} from '../lib/types'; - -import fsPromise from 'nuclide-commons/fsPromise'; -import {MessageStore} from '../lib/MessageStore'; -import BusySignalSingleton from '../lib/BusySignalSingleton'; - -describe('BusySignalSingleton', () => { - let messageStore: MessageStore; - let singleton: BusySignalSingleton; - let messages: Array>; - const options: BusySignalOptions = {debounce: false}; - - beforeEach(() => { - messageStore = new MessageStore(); - singleton = new BusySignalSingleton(messageStore); +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _fsPromise; + + + + + + + + + + + + + +function _load_fsPromise() {return _fsPromise = _interopRequireDefault(require('nuclide-commons/fsPromise'));}var _MessageStore; +function _load_MessageStore() {return _MessageStore = require('../lib/MessageStore');}var _BusySignalSingleton; +function _load_BusySignalSingleton() {return _BusySignalSingleton = _interopRequireDefault(require('../lib/BusySignalSingleton'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */describe('BusySignalSingleton', () => {let messageStore;let singleton;let messages;const options = { debounce: false };beforeEach(() => {messageStore = new (_MessageStore || _load_MessageStore()).MessageStore();singleton = new (_BusySignalSingleton || _load_BusySignalSingleton()).default(messageStore); messages = []; - messageStore - .getMessageStream() - .skip(1) - .subscribe(elements => { - const strings = [...elements].map(element => { - const titleElement = element.getTitleElement(); - const child = - titleElement != null && titleElement.childNodes.length >= 1 - ? titleElement.childNodes[0] - : {}; - return child.data != null && typeof child.data === 'string' - ? child.data - : ''; - }); - messages.push(strings); + messageStore. + getMessageStream(). + skip(1). + subscribe(elements => { + const strings = [...elements].map(element => { + const titleElement = element.getTitleElement(); + const child = + titleElement != null && titleElement.childNodes.length >= 1 ? + titleElement.childNodes[0] : + {}; + return child.data != null && typeof child.data === 'string' ? + child.data : + ''; }); + messages.push(strings); + }); }); it('should record messages before and after a call', () => { @@ -49,22 +49,22 @@ describe('BusySignalSingleton', () => { singleton.reportBusyWhile('foo', () => Promise.resolve(5), options); expect(messages.length).toBe(1); waitsFor( - () => messages.length === 2, - 'It should publish a second message', - 100, - ); + () => messages.length === 2, + 'It should publish a second message', + 100); + }); it("should send the 'done' message even if the promise rejects", () => { - singleton - .reportBusyWhile('foo', () => Promise.reject(new Error()), options) - .catch(() => {}); + singleton. + reportBusyWhile('foo', () => Promise.reject(new Error()), options). + catch(() => {}); expect(messages.length).toBe(1); waitsFor( - () => messages.length === 2, - 'It should publish a second message', - 100, - ); + () => messages.length === 2, + 'It should publish a second message', + 100); + }); it('should properly display duplicate messages', () => { @@ -86,18 +86,18 @@ describe('BusySignalSingleton', () => { }); describe('when onlyForFile is provided', () => { - let editor1: atom$TextEditor = (null: any); - let editor2: atom$TextEditor = (null: any); - let editor3: atom$TextEditor = (null: any); + let editor1 = null; + let editor2 = null; + let editor3 = null; let file2; beforeEach(() => { - waitsForPromise(async () => { - editor1 = await atom.workspace.open(await fsPromise.tempfile()); - file2 = await fsPromise.tempfile(); - editor2 = await atom.workspace.open(file2); - editor3 = await atom.workspace.open(); - }); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + editor1 = yield atom.workspace.open((yield (_fsPromise || _load_fsPromise()).default.tempfile())); + file2 = yield (_fsPromise || _load_fsPromise()).default.tempfile(); + editor2 = yield atom.workspace.open(file2); + editor3 = yield atom.workspace.open(); + })); }); afterEach(() => { @@ -107,10 +107,10 @@ describe('BusySignalSingleton', () => { it('should only display for the proper text editor', () => { atom.workspace.getActivePane().activateItem(editor1); - const disposable = singleton.reportBusy('foo', { - onlyForFile: file2, - ...options, - }); + const disposable = singleton.reportBusy('foo', Object.assign({ + onlyForFile: file2 }, + options)); + expect(messages).toEqual([]); atom.workspace.getActivePane().activateItem(editor2); @@ -132,21 +132,21 @@ describe('BusySignalSingleton', () => { }); it('correctly sets revealTooltip when provided', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { function getCurrentMessages() { - return messageStore - .getMessageStream() - .take(1) - .toPromise(); + return messageStore. + getMessageStream(). + take(1). + toPromise(); } singleton.reportBusy('foo', { debounce: false, - revealTooltip: true, - }); - const curMessages = await getCurrentMessages(); + revealTooltip: true }); + + const curMessages = yield getCurrentMessages(); expect(curMessages.length).toBe(1); expect(curMessages[0].shouldRevealTooltip()).toBe(true); - }); + })); }); -}); +}); \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-code-actions/lib/CodeActionManager.js b/modules/atom-ide-ui/pkg/atom-ide-code-actions/lib/CodeActionManager.js index 0bfc072d..cf3b6bd3 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-code-actions/lib/CodeActionManager.js +++ b/modules/atom-ide-ui/pkg/atom-ide-code-actions/lib/CodeActionManager.js @@ -1,206 +1,205 @@ -/** - * 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 - * @format - */ - -import {observeActiveEditorsDebounced} from 'nuclide-commons-atom/debounced'; -import ProviderRegistry from 'nuclide-commons-atom/ProviderRegistry'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {arrayCompact, arrayFlatten} from 'nuclide-commons/collection'; -import {Observable} from 'rxjs'; -import {getLogger} from 'log4js'; - -import type { - RegisterIndieLinter, - IndieLinterDelegate, - LinterMessageV2, -} from '../../../index'; -import type { - DiagnosticMessage, - DiagnosticUpdater, -} from '../../atom-ide-diagnostics/lib/types'; -import type {CodeAction, CodeActionProvider, CodeActionFetcher} from './types'; - -const TIP_DELAY_MS = 500; - -async function actionsToMessage( - location: {file: string, position: atom$RangeLike}, - actions: Array, -): Promise { - const titles = await Promise.all(actions.map(r => r.getTitle())); - const solutions = titles.map((title, i) => ({ - title, - position: location.position, - apply: actions[i].apply.bind(actions[i]), - })); - return { - location, - solutions, - excerpt: 'Select an action', - severity: 'info', - kind: 'action', - }; -} - -export class CodeActionManager { - _providerRegistry: ProviderRegistry; - _disposables: UniversalDisposable; - _linterDelegate: ?IndieLinterDelegate; - _diagnosticUpdater: ?DiagnosticUpdater; - - constructor() { - this._providerRegistry = new ProviderRegistry(); - this._disposables = new UniversalDisposable(this._selectionSubscriber()); +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.CodeActionManager = undefined;var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));let actionsToMessage = (() => {var _ref = (0, _asyncToGenerator.default)( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + function* ( + location, + actions) + { + const titles = yield Promise.all(actions.map(function (r) {return r.getTitle();})); + const solutions = titles.map(function (title, i) {return { + title, + position: location.position, + apply: actions[i].apply.bind(actions[i]) };}); + + return { + location, + solutions, + excerpt: 'Select an action', + severity: 'info', + kind: 'action' }; + + });return function actionsToMessage(_x, _x2) {return _ref.apply(this, arguments);};})();var _debounced;function _load_debounced() {return _debounced = require('nuclide-commons-atom/debounced');}var _ProviderRegistry;function _load_ProviderRegistry() {return _ProviderRegistry = _interopRequireDefault(require('nuclide-commons-atom/ProviderRegistry'));}var _event;function _load_event() {return _event = require('nuclide-commons/event');}var _UniversalDisposable;function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _collection;function _load_collection() {return _collection = require('nuclide-commons/collection');}var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _log4js;function _load_log4js() {return _log4js = require('log4js');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}const TIP_DELAY_MS = 500; /** + * 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. + * + * + * @format + */class CodeActionManager {constructor() {this._providerRegistry = new (_ProviderRegistry || _load_ProviderRegistry()).default();this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(this._selectionSubscriber()); } dispose() { this._disposables.dispose(); } - addProvider(provider: CodeActionProvider): IDisposable { + addProvider(provider) { const disposable = this._providerRegistry.addProvider(provider); this._disposables.add(disposable); return disposable; } - consumeDiagnosticUpdates(diagnosticUpdater: DiagnosticUpdater): IDisposable { + consumeDiagnosticUpdates(diagnosticUpdater) { this._diagnosticUpdater = diagnosticUpdater; - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { this._diagnosticUpdater = null; }); } - consumeIndie(register: RegisterIndieLinter): IDisposable { + consumeIndie(register) { const linterDelegate = register({ name: 'Code Actions', - supportedMessageKinds: ['action'], - }); + supportedMessageKinds: ['action'] }); + this._disposables.add(linterDelegate); this._linterDelegate = linterDelegate; - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { this._disposables.remove(linterDelegate); this._linterDelegate = null; }); } - async _genAllCodeActions( - editor: atom$TextEditor, - range: atom$Range, - diagnostics: Array, - ): Promise> { - const codeActionRequests = []; - for (const provider of this._providerRegistry.getAllProvidersForEditor( - editor, - )) { - codeActionRequests.push( - provider.getCodeActions(editor, range, diagnostics), - ); - } - return arrayFlatten(arrayCompact(await Promise.all(codeActionRequests))); + _genAllCodeActions( + editor, + range, + diagnostics) + {var _this = this;return (0, _asyncToGenerator.default)(function* () { + const codeActionRequests = []; + for (const provider of _this._providerRegistry.getAllProvidersForEditor( + editor)) + { + codeActionRequests.push( + provider.getCodeActions(editor, range, diagnostics)); + + } + return (0, (_collection || _load_collection()).arrayFlatten)((0, (_collection || _load_collection()).arrayCompact)((yield Promise.all(codeActionRequests))));})(); } - createCodeActionFetcher(): CodeActionFetcher { + createCodeActionFetcher() { return { getCodeActionForDiagnostic: (diagnostic, editor) => { if (diagnostic.range) { - const {range} = diagnostic; + const { range } = diagnostic; return this._genAllCodeActions(editor, range, [diagnostic]); } return Promise.resolve([]); - }, - }; + } }; + } // Listen to buffer range selection changes and trigger code action providers // when ranges change. - _selectionSubscriber(): rxjs$Subscription { + _selectionSubscriber() { // Patterned after highlightEditors of CodeHighlightManager. - return observeActiveEditorsDebounced(0) - .switchMap( - // Get selections for the active editor. - editor => { - if (editor == null) { - return Observable.empty(); - } - const destroyEvents = observableFromSubscribeFunction( - editor.onDidDestroy.bind(editor), - ); - const selections = observableFromSubscribeFunction( - editor.onDidChangeSelectionRange.bind(editor), - ) - .switchMap( - event => - // Remove 0-character selections since it's just cursor movement. - event.newBufferRange.isEmpty() - ? Observable.of(null) - : Observable.of(event.newBufferRange) - .delay(TIP_DELAY_MS) // Delay the emission of the range. - .startWith(null), // null the range immediately when selection changes. - ) - .distinctUntilChanged() - .takeUntil(destroyEvents); - return selections.map( - range => (range == null ? null : {editor, range}), - ); - }, - ) - .switchMap( - // Get a message for the provided selection. - (selection: ?{editor: atom$TextEditor, range: atom$Range}) => { - if (selection == null) { - return Observable.of(null); - } - const {editor, range} = selection; - const file = editor.getBuffer().getPath(); - if (file == null) { - return Observable.empty(); - } - const diagnostics = - this._diagnosticUpdater == null - ? [] - : this._diagnosticUpdater - .getFileMessageUpdates(file) - .messages.filter( - message => - message.range && message.range.intersectsWith(range), - ); - return Observable.fromPromise( - this._genAllCodeActions(editor, range, diagnostics), - ).switchMap(actions => { - // Only produce a message if we have actions to display. - if (actions.length > 0) { - return actionsToMessage({file, position: range}, actions); - } else { - return Observable.empty(); - } - }); - }, - ) - .distinctUntilChanged() - .catch((e, caught) => { - getLogger('code-actions').error( - 'Error getting code actions on selection', - e, - ); - return caught; - }) - .subscribe(message => { - if (this._linterDelegate == null) { - return; - } - if (message == null) { - this._linterDelegate.clearMessages(); + return (0, (_debounced || _load_debounced()).observeActiveEditorsDebounced)(0). + switchMap( + // Get selections for the active editor. + editor => { + if (editor == null) { + return _rxjsBundlesRxMinJs.Observable.empty(); + } + const destroyEvents = (0, (_event || _load_event()).observableFromSubscribeFunction)( + editor.onDidDestroy.bind(editor)); + + const selections = (0, (_event || _load_event()).observableFromSubscribeFunction)( + editor.onDidChangeSelectionRange.bind(editor)). + + switchMap( + event => + // Remove 0-character selections since it's just cursor movement. + event.newBufferRange.isEmpty() ? + _rxjsBundlesRxMinJs.Observable.of(null) : + _rxjsBundlesRxMinJs.Observable.of(event.newBufferRange). + delay(TIP_DELAY_MS) // Delay the emission of the range. + .startWith(null) // null the range immediately when selection changes. + ). + distinctUntilChanged(). + takeUntil(destroyEvents); + return selections.map( + range => range == null ? null : { editor, range }); + + }). + + switchMap( + // Get a message for the provided selection. + selection => { + if (selection == null) { + return _rxjsBundlesRxMinJs.Observable.of(null); + } + const { editor, range } = selection; + const file = editor.getBuffer().getPath(); + if (file == null) { + return _rxjsBundlesRxMinJs.Observable.empty(); + } + const diagnostics = + this._diagnosticUpdater == null ? + [] : + this._diagnosticUpdater. + getFileMessageUpdates(file). + messages.filter( + message => + message.range && message.range.intersectsWith(range)); + + return _rxjsBundlesRxMinJs.Observable.fromPromise( + this._genAllCodeActions(editor, range, diagnostics)). + switchMap(actions => { + // Only produce a message if we have actions to display. + if (actions.length > 0) { + return actionsToMessage({ file, position: range }, actions); } else { - this._linterDelegate.setAllMessages([message]); + return _rxjsBundlesRxMinJs.Observable.empty(); } }); - } -} + }). + + distinctUntilChanged(). + catch((e, caught) => { + (0, (_log4js || _load_log4js()).getLogger)('code-actions').error( + 'Error getting code actions on selection', + e); + + return caught; + }). + subscribe(message => { + if (this._linterDelegate == null) { + return; + } + if (message == null) { + this._linterDelegate.clearMessages(); + } else { + this._linterDelegate.setAllMessages([message]); + } + }); + }}exports.CodeActionManager = CodeActionManager; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-code-actions/lib/main.js b/modules/atom-ide-ui/pkg/atom-ide-code-actions/lib/main.js index cc068c15..b92f17be 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-code-actions/lib/main.js +++ b/modules/atom-ide-ui/pkg/atom-ide-code-actions/lib/main.js @@ -1,48 +1,48 @@ -/** - * 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 - * @format - */ - -import createPackage from 'nuclide-commons-atom/createPackage'; -import {CodeActionManager} from './CodeActionManager'; - -import type {RegisterIndieLinter} from '../../../index'; -import type {CodeActionProvider, CodeActionFetcher} from './types'; -import type {DiagnosticUpdater} from '../../atom-ide-diagnostics/lib/types'; - -class Activation { - _codeActionManager: CodeActionManager; - - constructor() { - this._codeActionManager = new CodeActionManager(); +'use strict';var _createPackage; + + + + + + + + + + + +function _load_createPackage() {return _createPackage = _interopRequireDefault(require('nuclide-commons-atom/createPackage'));}var _CodeActionManager; +function _load_CodeActionManager() {return _CodeActionManager = require('./CodeActionManager');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */class Activation {constructor() {this._codeActionManager = new (_CodeActionManager || _load_CodeActionManager()).CodeActionManager(); } dispose() { this._codeActionManager.dispose(); } - consumeCodeActionProvider(provider: CodeActionProvider) { + consumeCodeActionProvider(provider) { return this._codeActionManager.addProvider(provider); } - consumeDiagnosticUpdates(diagnosticUpdater: DiagnosticUpdater) { + consumeDiagnosticUpdates(diagnosticUpdater) { return this._codeActionManager.consumeDiagnosticUpdates(diagnosticUpdater); } - provideCodeActionFetcher(): CodeActionFetcher { + provideCodeActionFetcher() { return this._codeActionManager.createCodeActionFetcher(); } - consumeIndie(register: RegisterIndieLinter) { + consumeIndie(register) { return this._codeActionManager.consumeIndie(register); - } -} + }} + -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-code-actions/lib/types.js b/modules/atom-ide-ui/pkg/atom-ide-code-actions/lib/types.js index 003f5366..a726efc4 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-code-actions/lib/types.js +++ b/modules/atom-ide-ui/pkg/atom-ide-code-actions/lib/types.js @@ -1,42 +1 @@ -/** - * 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 - * @format - */ - -import type {DiagnosticMessage} from '../../../pkg/atom-ide-diagnostics/lib/types'; - -export interface CodeAction { - apply(): Promise; - getTitle(): Promise; - dispose(): void; -} - -export type CodeActionProvider = { - +grammarScopes?: Array, - priority: number, - getCodeActions( - editor: atom$TextEditor, - range: atom$Range, - diagnostics: Array, - ): Promise>, -}; - -/** - * atom-ide-code-actions provides a CodeActionFetcher which offers an API to - * request CodeActions from all CodeAction providers. For now, CodeActionFetcher - * can only fetch CodeActions for a Diagnostic. In the future, this API can be - * extended to provide a stream of CodeActions based on the cursor position. - */ -export type CodeActionFetcher = { - getCodeActionForDiagnostic: ( - diagnostic: DiagnosticMessage, - editor: atom$TextEditor, - ) => Promise>, -}; +'use strict'; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-code-actions/spec/CodeActionManager-spec.js b/modules/atom-ide-ui/pkg/atom-ide-code-actions/spec/CodeActionManager-spec.js index 825aaf85..02148695 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-code-actions/spec/CodeActionManager-spec.js +++ b/modules/atom-ide-ui/pkg/atom-ide-code-actions/spec/CodeActionManager-spec.js @@ -1,19 +1,19 @@ -/** - * 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 - * @format - */ - -import os from 'os'; -import nuclideUri from 'nuclide-commons/nuclideUri'; - -import {CodeActionManager} from '../lib/CodeActionManager'; +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + + + + + + + + + + + +var _os = _interopRequireDefault(require('os'));var _nuclideUri; +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));}var _CodeActionManager; + +function _load_CodeActionManager() {return _CodeActionManager = require('../lib/CodeActionManager');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} describe('CodeActionManager', () => { let manager; @@ -22,39 +22,39 @@ describe('CodeActionManager', () => { let editor; beforeEach(() => { jasmine.useMockClock(); - waitsForPromise(async () => { - editor = await atom.workspace.open( - nuclideUri.join(os.tmpdir(), 'test.txt'), - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + editor = yield atom.workspace.open( + (_nuclideUri || _load_nuclideUri()).default.join(_os.default.tmpdir(), 'test.txt')); + editor.setText('abc\ndef\nghi'); - manager = new CodeActionManager(); + manager = new (_CodeActionManager || _load_CodeActionManager()).CodeActionManager(); provider = { priority: 1, grammarScopes: ['text.plain.null-grammar'], - async getCodeActions(_e, _r, _d) { - return []; - }, - }; + getCodeActions(_e, _r, _d) {return (0, _asyncToGenerator.default)(function* () { + return [];})(); + } }; + delegate = { - clearMessages: () => {}, - setAllMessages: _messages => {}, - }; - manager._linterDelegate = (delegate: any); + clearMessages: function () {}, + setAllMessages: function (_messages) {} }; + + manager._linterDelegate = delegate; manager.addProvider(provider); - }); + })); }); it('finds code actions on highlight change and updates linter', () => { const actions = [ - { - apply() {}, - async getTitle() { - return 'Mock action'; - }, - dispose() {}, + { + apply() {}, + getTitle() {return (0, _asyncToGenerator.default)(function* () { + return 'Mock action';})(); }, - ]; + dispose() {} }]; + + const spyActions = spyOn(provider, 'getCodeActions').andReturn(actions); const spyLinter = spyOn(delegate, 'setAllMessages'); @@ -65,17 +65,27 @@ describe('CodeActionManager', () => { }); waitsFor( - () => spyLinter.wasCalled, - 'should have called setAllMessages', - 750, - ); + () => spyLinter.wasCalled, + 'should have called setAllMessages', + 750); + runs(() => { expect(spyActions).toHaveBeenCalled(); expect(spyLinter).toHaveBeenCalled(); expect( - (spyLinter.mostRecentCall.args: any)[0][0].solutions.length, - ).toEqual(1); + spyLinter.mostRecentCall.args[0][0].solutions.length). + toEqual(1); }); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-code-format/lib/CodeFormatManager.js b/modules/atom-ide-ui/pkg/atom-ide-code-format/lib/CodeFormatManager.js index b978d2dd..c1e3159e 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-code-format/lib/CodeFormatManager.js +++ b/modules/atom-ide-ui/pkg/atom-ide-code-format/lib/CodeFormatManager.js @@ -1,137 +1,137 @@ -/** - * 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 - * @format - */ - -import type {BusySignalService} from '../../atom-ide-busy-signal/lib/types'; -import type { - RangeCodeFormatProvider, - FileCodeFormatProvider, - OnTypeCodeFormatProvider, - OnSaveCodeFormatProvider, -} from './types'; - -import {Range} from 'atom'; -import {Observable, Subject} from 'rxjs'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {completingSwitchMap, microtask} from 'nuclide-commons/observable'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import ProviderRegistry from 'nuclide-commons-atom/ProviderRegistry'; -import { - observeEditorDestroy, - observeTextEditors, -} from 'nuclide-commons-atom/text-editor'; -import {applyTextEditsToBuffer} from 'nuclide-commons-atom/text-edit'; -import {getFormatOnSave, getFormatOnType} from './config'; -import {getLogger} from 'log4js'; +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); + + + + + + + + + + + + + + + + + + + +var _atom = require('atom'); +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _event; +function _load_event() {return _event = require('nuclide-commons/event');}var _nuclideUri; +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));}var _observable; +function _load_observable() {return _observable = require('nuclide-commons/observable');}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _ProviderRegistry; +function _load_ProviderRegistry() {return _ProviderRegistry = _interopRequireDefault(require('nuclide-commons-atom/ProviderRegistry'));}var _textEditor; +function _load_textEditor() {return _textEditor = require('nuclide-commons-atom/text-editor');}var _textEdit; + + + +function _load_textEdit() {return _textEdit = require('nuclide-commons-atom/text-edit');}var _config; +function _load_config() {return _config = require('./config');}var _log4js; +function _load_log4js() {return _log4js = require('log4js');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} // Save events are critical, so don't allow providers to block them. -const SAVE_TIMEOUT = 2500; +const SAVE_TIMEOUT = 2500; /** + * 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. + * + * + * @format + */ + + +class CodeFormatManager { + + + + + -type FormatEvent = - | { - type: 'command' | 'save' | 'new-save', - editor: atom$TextEditor, - } - | { - type: 'type', - editor: atom$TextEditor, - edit: atom$AggregatedTextEditEvent, - }; - -export default class CodeFormatManager { - _subscriptions: UniversalDisposable; - _rangeProviders: ProviderRegistry; - _fileProviders: ProviderRegistry; - _onTypeProviders: ProviderRegistry; - _onSaveProviders: ProviderRegistry; - _busySignalService: ?BusySignalService; constructor() { - this._subscriptions = new UniversalDisposable(this._subscribeToEvents()); - this._rangeProviders = new ProviderRegistry(); - this._fileProviders = new ProviderRegistry(); - this._onTypeProviders = new ProviderRegistry(); - this._onSaveProviders = new ProviderRegistry(); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(this._subscribeToEvents()); + this._rangeProviders = new (_ProviderRegistry || _load_ProviderRegistry()).default(); + this._fileProviders = new (_ProviderRegistry || _load_ProviderRegistry()).default(); + this._onTypeProviders = new (_ProviderRegistry || _load_ProviderRegistry()).default(); + this._onSaveProviders = new (_ProviderRegistry || _load_ProviderRegistry()).default(); } /** - * Subscribe to all formatting events (commands, saves, edits) and dispatch - * formatters as necessary. - * By handling all events in a central location, we ensure that no buffer - * runs into race conditions with simultaneous formatters. - */ - _subscribeToEvents(): rxjs$Subscription { + * Subscribe to all formatting events (commands, saves, edits) and dispatch + * formatters as necessary. + * By handling all events in a central location, we ensure that no buffer + * runs into race conditions with simultaneous formatters. + */ + _subscribeToEvents() { // Events from the explicit Atom command. - const commandEvents = observableFromSubscribeFunction(callback => - atom.commands.add( - 'atom-text-editor', - 'code-format:format-code', - callback, - ), - ).switchMap(() => { + const commandEvents = (0, (_event || _load_event()).observableFromSubscribeFunction)(callback => + atom.commands.add( + 'atom-text-editor', + 'code-format:format-code', + callback)). + + switchMap(() => { const editor = atom.workspace.getActiveTextEditor(); if (!editor) { - return Observable.empty(); + return _rxjsBundlesRxMinJs.Observable.empty(); } - return Observable.of({type: 'command', editor}); + return _rxjsBundlesRxMinJs.Observable.of({ type: 'command', editor }); }); // Events from editor actions (saving, typing). - const editorEvents = observableFromSubscribeFunction( - observeTextEditors, - ).mergeMap(editor => this._getEditorEventStream(editor)); + const editorEvents = (0, (_event || _load_event()).observableFromSubscribeFunction)((_textEditor || _load_textEditor()).observeTextEditors). + + mergeMap(editor => this._getEditorEventStream(editor)); return ( - Observable.merge(commandEvents, editorEvents) - // Group events by buffer to prevent simultaneous formatting operations. - .groupBy( - event => event.editor.getBuffer(), - event => event, - grouped => - observableFromSubscribeFunction(callback => - grouped.key.onDidDestroy(callback), - ), - ) - .mergeMap(events => - // Make sure we halt everything when the editor gets destroyed. - events.let(completingSwitchMap(event => this._handleEvent(event))), - ) - .subscribe() - ); + _rxjsBundlesRxMinJs.Observable.merge(commandEvents, editorEvents) + // Group events by buffer to prevent simultaneous formatting operations. + .groupBy( + event => event.editor.getBuffer(), + event => event, + grouped => + (0, (_event || _load_event()).observableFromSubscribeFunction)(callback => + grouped.key.onDidDestroy(callback))). + + + mergeMap(events => + // Make sure we halt everything when the editor gets destroyed. + events.let((0, (_observable || _load_observable()).completingSwitchMap)(event => this._handleEvent(event)))). + + subscribe()); + } /** - * Returns a stream of all typing and saving operations from the editor. - */ - _getEditorEventStream(editor: atom$TextEditor): Observable { - const changeEvents = observableFromSubscribeFunction(callback => - editor.getBuffer().onDidChangeText(callback), - ); + * Returns a stream of all typing and saving operations from the editor. + */ + _getEditorEventStream(editor) { + const changeEvents = (0, (_event || _load_event()).observableFromSubscribeFunction)(callback => + editor.getBuffer().onDidChangeText(callback)); + - const saveEvents = Observable.create(observer => { + const saveEvents = _rxjsBundlesRxMinJs.Observable.create(observer => { const realSave = editor.save; - const newSaves = new Subject(); + const newSaves = new _rxjsBundlesRxMinJs.Subject(); // HACK: intercept the real TextEditor.save and handle it ourselves. // Atom has no way of injecting content into the buffer asynchronously // before a save operation. // If we try to format after the save, and then save again, // it's a poor user experience (and also races the text buffer's reload). - const editor_ = (editor: any); + const editor_ = editor; editor_.save = () => { newSaves.next('new-save'); - return this._safeFormatCodeOnSave(editor) - .takeUntil(newSaves) - .toPromise() - .then(() => realSave.call(editor)); + return this._safeFormatCodeOnSave(editor). + takeUntil(newSaves). + toPromise(). + then(() => realSave.call(editor)); }; const subscription = newSaves.subscribe(observer); return () => { @@ -144,83 +144,83 @@ export default class CodeFormatManager { // We need to capture when editors are about to be destroyed in order to // interrupt any pending formatting operations. (Otherwise, we may end up // attempting to save a destroyed editor!) - const willDestroyEvents = observableFromSubscribeFunction(cb => - atom.workspace.onWillDestroyPaneItem(cb), - ).filter(event => event.item === editor); - - return Observable.merge( - changeEvents.map(edit => ({type: 'type', editor, edit})), - saveEvents.map(type => ({type, editor})), - ).takeUntil( - Observable.merge(observeEditorDestroy(editor), willDestroyEvents), - ); + const willDestroyEvents = (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => + atom.workspace.onWillDestroyPaneItem(cb)). + filter(event => event.item === editor); + + return _rxjsBundlesRxMinJs.Observable.merge( + changeEvents.map(edit => ({ type: 'type', editor, edit })), + saveEvents.map(type => ({ type, editor }))). + takeUntil( + _rxjsBundlesRxMinJs.Observable.merge((0, (_textEditor || _load_textEditor()).observeEditorDestroy)(editor), willDestroyEvents)); + } - _handleEvent(event: FormatEvent): Observable { - const {editor} = event; + _handleEvent(event) { + const { editor } = event; switch (event.type) { case 'command': - return this._formatCodeInTextEditor(editor) - .map(result => { - if (!result) { - throw new Error('No code formatting providers found!'); - } - }) - .catch(err => { - atom.notifications.addError( - `Failed to format code: ${err.message}`, - { - detail: err.detail, - }, - ); - return Observable.empty(); - }); + return this._formatCodeInTextEditor(editor). + map(result => { + if (!result) { + throw new Error('No code formatting providers found!'); + } + }). + catch(err => { + atom.notifications.addError( + `Failed to format code: ${err.message}`, + { + detail: err.detail }); + + + return _rxjsBundlesRxMinJs.Observable.empty(); + }); case 'type': return this._formatCodeOnTypeInTextEditor(editor, event.edit).catch( - err => { - getLogger('code-format').warn( - 'Failed to format code on type:', - err, - ); - return Observable.empty(); - }, - ); + err => { + (0, (_log4js || _load_log4js()).getLogger)('code-format').warn( + 'Failed to format code on type:', + err); + + return _rxjsBundlesRxMinJs.Observable.empty(); + }); + case 'save': return ( this._safeFormatCodeOnSave(editor) - // Fire-and-forget the original save function. - // This is actually async for remote files, but we don't use the result. - // NOTE: finally is important, as saves should still fire on unsubscribe. - .finally(() => editor.getBuffer().save()) - ); + // Fire-and-forget the original save function. + // This is actually async for remote files, but we don't use the result. + // NOTE: finally is important, as saves should still fire on unsubscribe. + .finally(() => editor.getBuffer().save())); + case 'new-save': - return Observable.empty(); + return _rxjsBundlesRxMinJs.Observable.empty(); default: - return Observable.throw(`unknown event type ${event.type}`); - } + return _rxjsBundlesRxMinJs.Observable.throw(`unknown event type ${event.type}`);} + } // Checks whether contents are same in the buffer post-format, throwing if // anything has changed. - _checkContentsAreSame(before: string, after: string): void { + _checkContentsAreSame(before, after) { if (before !== after) { throw new Error( - 'The file contents were changed before formatting was complete.', - ); + 'The file contents were changed before formatting was complete.'); + } } // Formats code in the editor specified, returning whether or not a // code formatter completed successfully. _formatCodeInTextEditor( - editor: atom$TextEditor, - range?: atom$Range, - ): Observable { - return Observable.defer(() => { + editor, + range) + { + return _rxjsBundlesRxMinJs.Observable.defer(() => { const buffer = editor.getBuffer(); const selectionRange = range || editor.getSelectedBufferRange(); - const {start: selectionStart, end: selectionEnd} = selectionRange; - let formatRange: atom$Range; + const { start: selectionStart, end: selectionEnd } = selectionRange; + let formatRange; if (selectionRange.isEmpty()) { // If no selection is done, then, the whole file is wanted to be formatted. formatRange = buffer.getRange(); @@ -232,47 +232,47 @@ export default class CodeFormatManager { // or (2) at the first column of the line AFTER their selection. In both cases // we snap the formatRange to end at the first column of the line after their // selection.) - formatRange = new Range( - [selectionStart.row, 0], - selectionEnd.column === 0 ? selectionEnd : [selectionEnd.row + 1, 0], - ); + formatRange = new _atom.Range( + [selectionStart.row, 0], + selectionEnd.column === 0 ? selectionEnd : [selectionEnd.row + 1, 0]); + } const rangeProvider = this._rangeProviders.getProviderForEditor(editor); const fileProvider = this._fileProviders.getProviderForEditor(editor); const contents = editor.getText(); if ( - rangeProvider != null && - // When formatting the entire file, prefer file-based providers. - (!formatRange.isEqual(buffer.getRange()) || fileProvider == null) - ) { - return Observable.defer(() => - this._reportBusy( - editor, - rangeProvider.formatCode(editor, formatRange), - ), - ).map(edits => { + rangeProvider != null && ( + // When formatting the entire file, prefer file-based providers. + !formatRange.isEqual(buffer.getRange()) || fileProvider == null)) + { + return _rxjsBundlesRxMinJs.Observable.defer(() => + this._reportBusy( + editor, + rangeProvider.formatCode(editor, formatRange))). + + map(edits => { // Throws if contents have changed since the time of triggering format code. this._checkContentsAreSame(contents, editor.getText()); - if (!applyTextEditsToBuffer(editor.getBuffer(), edits)) { + if (!(0, (_textEdit || _load_textEdit()).applyTextEditsToBuffer)(editor.getBuffer(), edits)) { throw new Error('Could not apply edits to text buffer.'); } return true; }); } else if (fileProvider != null) { - return Observable.defer(() => - this._reportBusy( - editor, - fileProvider.formatEntireFile(editor, formatRange), - ), - ).map(({newCursor, formatted}) => { + return _rxjsBundlesRxMinJs.Observable.defer(() => + this._reportBusy( + editor, + fileProvider.formatEntireFile(editor, formatRange))). + + map(({ newCursor, formatted }) => { // Throws if contents have changed since the time of triggering format code. this._checkContentsAreSame(contents, editor.getText()); buffer.setTextViaDiff(formatted); const newPosition = - newCursor != null - ? buffer.positionForCharacterIndex(newCursor) - : editor.getCursorBufferPosition(); + newCursor != null ? + buffer.positionForCharacterIndex(newCursor) : + editor.getCursorBufferPosition(); // We call setCursorBufferPosition even when there is no newCursor, // because it unselects the text selection. @@ -280,24 +280,24 @@ export default class CodeFormatManager { return true; }); } else { - return Observable.of(false); + return _rxjsBundlesRxMinJs.Observable.of(false); } }); } _formatCodeOnTypeInTextEditor( - editor: atom$TextEditor, - aggregatedEvent: atom$AggregatedTextEditEvent, - ): Observable { - return Observable.defer(() => { + editor, + aggregatedEvent) + { + return _rxjsBundlesRxMinJs.Observable.defer(() => { // Don't try to format changes with multiple cursors. if (aggregatedEvent.changes.length !== 1) { - return Observable.empty(); + return _rxjsBundlesRxMinJs.Observable.empty(); } const event = aggregatedEvent.changes[0]; // This also ensures the non-emptiness of event.newText for below. - if (!shouldFormatOnType(event) || !getFormatOnType()) { - return Observable.empty(); + if (!shouldFormatOnType(event) || !(0, (_config || _load_config()).getFormatOnType)()) { + return _rxjsBundlesRxMinJs.Observable.empty(); } // In the case of bracket-matching, we use the last character because that's // the character that will usually cause a reformat (i.e. `}` instead of `{`). @@ -305,7 +305,7 @@ export default class CodeFormatManager { const provider = this._onTypeProviders.getProviderForEditor(editor); if (provider == null) { - return Observable.empty(); + return _rxjsBundlesRxMinJs.Observable.empty(); } const contents = editor.getText(); @@ -322,104 +322,104 @@ export default class CodeFormatManager { // We want to wait until the cursor has actually moved before we issue a // format request, so that we format at the right position (and potentially // also let any other event handlers have their go). - return microtask - .switchMap(() => - provider.formatAtPosition( - editor, - editor.getCursorBufferPosition().translate([0, -1]), - character, - ), - ) - .map(edits => { - if (edits.length === 0) { - return; - } - this._checkContentsAreSame(contents, editor.getText()); - // Note that this modification is not in a transaction, so it applies as a - // separate editing event than the character typing. This means that you - // can undo just the formatting by attempting to undo once, and then undo - // your actual code by undoing again. - if (!applyTextEditsToBuffer(editor.getBuffer(), edits)) { - throw new Error('Could not apply edits to text buffer.'); - } - }); + return (_observable || _load_observable()).microtask. + switchMap(() => + provider.formatAtPosition( + editor, + editor.getCursorBufferPosition().translate([0, -1]), + character)). + + + map(edits => { + if (edits.length === 0) { + return; + } + this._checkContentsAreSame(contents, editor.getText()); + // Note that this modification is not in a transaction, so it applies as a + // separate editing event than the character typing. This means that you + // can undo just the formatting by attempting to undo once, and then undo + // your actual code by undoing again. + if (!(0, (_textEdit || _load_textEdit()).applyTextEditsToBuffer)(editor.getBuffer(), edits)) { + throw new Error('Could not apply edits to text buffer.'); + } + }); }); } - _safeFormatCodeOnSave(editor: atom$TextEditor): Observable { - return this._formatCodeOnSaveInTextEditor(editor) - .timeout(SAVE_TIMEOUT) - .catch(err => { - getLogger('code-format').warn('Failed to format code on save:', err); - return Observable.empty(); - }); + _safeFormatCodeOnSave(editor) { + return this._formatCodeOnSaveInTextEditor(editor). + timeout(SAVE_TIMEOUT). + catch(err => { + (0, (_log4js || _load_log4js()).getLogger)('code-format').warn('Failed to format code on save:', err); + return _rxjsBundlesRxMinJs.Observable.empty(); + }); } - _formatCodeOnSaveInTextEditor(editor: atom$TextEditor): Observable { + _formatCodeOnSaveInTextEditor(editor) { const saveProvider = this._onSaveProviders.getProviderForEditor(editor); if (saveProvider != null) { - return Observable.defer(() => - this._reportBusy(editor, saveProvider.formatOnSave(editor), false), - ).map(edits => { - applyTextEditsToBuffer(editor.getBuffer(), edits); + return _rxjsBundlesRxMinJs.Observable.defer(() => + this._reportBusy(editor, saveProvider.formatOnSave(editor), false)). + map(edits => { + (0, (_textEdit || _load_textEdit()).applyTextEditsToBuffer)(editor.getBuffer(), edits); }); - } else if (getFormatOnSave(editor)) { + } else if ((0, (_config || _load_config()).getFormatOnSave)(editor)) { return this._formatCodeInTextEditor( - editor, - editor.getBuffer().getRange(), - ).ignoreElements(); + editor, + editor.getBuffer().getRange()). + ignoreElements(); } - return Observable.empty(); + return _rxjsBundlesRxMinJs.Observable.empty(); } - _reportBusy( - editor: atom$TextEditor, - promise: Promise, - revealTooltip?: boolean = true, - ): Promise { + _reportBusy( + editor, + promise, + revealTooltip = true) + { const busySignalService = this._busySignalService; if (busySignalService != null) { const path = editor.getPath(); const displayPath = - path != null ? nuclideUri.basename(path) : ''; + path != null ? (_nuclideUri || _load_nuclideUri()).default.basename(path) : ''; return busySignalService.reportBusyWhile( - `Formatting code in ${displayPath}`, - () => promise, - {revealTooltip}, - ); + `Formatting code in ${displayPath}`, + () => promise, + { revealTooltip }); + } return promise; } - addRangeProvider(provider: RangeCodeFormatProvider): IDisposable { + addRangeProvider(provider) { return this._rangeProviders.addProvider(provider); } - addFileProvider(provider: FileCodeFormatProvider): IDisposable { + addFileProvider(provider) { return this._fileProviders.addProvider(provider); } - addOnTypeProvider(provider: OnTypeCodeFormatProvider): IDisposable { + addOnTypeProvider(provider) { return this._onTypeProviders.addProvider(provider); } - addOnSaveProvider(provider: OnSaveCodeFormatProvider): IDisposable { + addOnSaveProvider(provider) { return this._onSaveProviders.addProvider(provider); } - consumeBusySignal(busySignalService: BusySignalService): IDisposable { + consumeBusySignal(busySignalService) { this._busySignalService = busySignalService; - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { this._busySignalService = null; }); } dispose() { this._subscriptions.dispose(); - } -} + }}exports.default = CodeFormatManager; -function shouldFormatOnType(event: atom$TextEditEvent): boolean { + +function shouldFormatOnType(event) { // There's not a direct way to figure out what caused this edit event. There // are three cases that we want to pay attention to: // @@ -449,16 +449,16 @@ function shouldFormatOnType(event: atom$TextEditEvent): boolean { } /** - * We can't tell the difference between a paste and the bracket-matcher package - * inserting an extra bracket, so we just assume that any pair of brackets that - * bracket-matcher recognizes was a pair matched by the package. - */ -function isBracketPair(typedText: string): boolean { + * We can't tell the difference between a paste and the bracket-matcher package + * inserting an extra bracket, so we just assume that any pair of brackets that + * bracket-matcher recognizes was a pair matched by the package. + */ +function isBracketPair(typedText) { if (atom.packages.getActivePackage('bracket-matcher') == null) { return false; } - const validBracketPairs: Array = (atom.config.get( - 'bracket-matcher.autocompleteCharacters', - ): any); + const validBracketPairs = atom.config.get( + 'bracket-matcher.autocompleteCharacters'); + return validBracketPairs.indexOf(typedText) !== -1; -} +} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-code-format/lib/config.js b/modules/atom-ide-ui/pkg/atom-ide-code-format/lib/config.js index b80cc1e3..9d354f76 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-code-format/lib/config.js +++ b/modules/atom-ide-ui/pkg/atom-ide-code-format/lib/config.js @@ -1,27 +1,32 @@ -/** - * 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 - * @format - */ - -import featureConfig from 'nuclide-commons-atom/feature-config'; - -export function getFormatOnSave(editor: atom$TextEditor): boolean { - const formatOnSave = (featureConfig.get('atom-ide-code-format.formatOnSave', { - scope: editor.getRootScopeDescriptor(), - }): any); - return formatOnSave == null ? false : formatOnSave; -} - -export function getFormatOnType(): boolean { - return featureConfig.getWithDefaults( - 'atom-ide-code-format.formatOnType', - false, - ); -} +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + +getFormatOnSave = getFormatOnSave;exports. + + + + + + +getFormatOnType = getFormatOnType;var _featureConfig;function _load_featureConfig() {return _featureConfig = _interopRequireDefault(require('nuclide-commons-atom/feature-config'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function getFormatOnSave(editor) {const formatOnSave = (_featureConfig || _load_featureConfig()).default.get('atom-ide-code-format.formatOnSave', { scope: editor.getRootScopeDescriptor() });return formatOnSave == null ? false : formatOnSave;} /** + * 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. + * + * + * @format + */function getFormatOnType() {return (_featureConfig || _load_featureConfig()).default.getWithDefaults('atom-ide-code-format.formatOnType', false);} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-code-format/lib/main.js b/modules/atom-ide-ui/pkg/atom-ide-code-format/lib/main.js index 87cc462e..aedadeb1 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-code-format/lib/main.js +++ b/modules/atom-ide-ui/pkg/atom-ide-code-format/lib/main.js @@ -1,45 +1,45 @@ -/** - * 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 - * @format - */ - -import type {BusySignalService} from '../../atom-ide-busy-signal/lib/types'; -import type { - CodeFormatProvider, - RangeCodeFormatProvider, - FileCodeFormatProvider, - OnTypeCodeFormatProvider, - OnSaveCodeFormatProvider, -} from './types'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import CodeFormatManager from './CodeFormatManager'; - -class Activation { - codeFormatManager: CodeFormatManager; - - constructor() { - this.codeFormatManager = new CodeFormatManager(); - } +'use strict';var _createPackage; + + + + + + + + + + - consumeLegacyProvider(provider: CodeFormatProvider): IDisposable { - // Legacy providers used `selector` / `inclusionPriority`. + + + + + + + + + +function _load_createPackage() {return _createPackage = _interopRequireDefault(require('nuclide-commons-atom/createPackage'));}var _CodeFormatManager; +function _load_CodeFormatManager() {return _CodeFormatManager = _interopRequireDefault(require('./CodeFormatManager'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */class Activation {constructor() {this.codeFormatManager = new (_CodeFormatManager || _load_CodeFormatManager()).default();}consumeLegacyProvider(provider) {// Legacy providers used `selector` / `inclusionPriority`. provider.grammarScopes = - provider.grammarScopes || - (provider.selector != null ? provider.selector.split(', ') : null); + provider.grammarScopes || ( + provider.selector != null ? provider.selector.split(', ') : null); provider.priority = - provider.priority != null - ? provider.priority - : provider.inclusionPriority != null - ? provider.inclusionPriority - : 0; + provider.priority != null ? + provider.priority : + provider.inclusionPriority != null ? + provider.inclusionPriority : + 0; if (provider.formatCode) { return this.consumeRangeProvider(provider); } else if (provider.formatEntireFile) { @@ -52,29 +52,29 @@ class Activation { throw new Error('Invalid code format provider'); } - consumeRangeProvider(provider: RangeCodeFormatProvider): IDisposable { + consumeRangeProvider(provider) { return this.codeFormatManager.addRangeProvider(provider); } - consumeFileProvider(provider: FileCodeFormatProvider): IDisposable { + consumeFileProvider(provider) { return this.codeFormatManager.addFileProvider(provider); } - consumeOnTypeProvider(provider: OnTypeCodeFormatProvider): IDisposable { + consumeOnTypeProvider(provider) { return this.codeFormatManager.addOnTypeProvider(provider); } - consumeOnSaveProvider(provider: OnSaveCodeFormatProvider): IDisposable { + consumeOnSaveProvider(provider) { return this.codeFormatManager.addOnSaveProvider(provider); } - consumeBusySignal(busySignalService: BusySignalService): IDisposable { + consumeBusySignal(busySignalService) { return this.codeFormatManager.consumeBusySignal(busySignalService); } dispose() { this.codeFormatManager.dispose(); - } -} + }} + -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-code-format/lib/types.js b/modules/atom-ide-ui/pkg/atom-ide-code-format/lib/types.js index 971a82d6..a726efc4 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-code-format/lib/types.js +++ b/modules/atom-ide-ui/pkg/atom-ide-code-format/lib/types.js @@ -1,96 +1 @@ -/** - * 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 - * @format - */ - -import type {TextEdit} from 'nuclide-commons-atom/text-edit'; - -/** - * A brief overview of the different code formatting providers: - * - * == Range formatters == - * These accept a range to format and return a list of edits to apply. - * These will always be preferred over file formatters when a range is selected. - * - * == File formatters == - * These always return the result of formatting the entire file. - * To compensate, they can return a custom cursor position to avoid disruption. - * These will be preferred over range formatters for whole-file formatting. - * - * == onType formatters == - * These are run after every typing event in a selected editor. - * - * == onSave formatters == - * These are run whenever a selected editor is saved. - * If the global format-on-save option is enabled, then file/range formatters - * will be triggered on save (even if no save formatters are provided). - * Obviously, save formatters are preferred in this case. - */ - -/** - * Formats the range specified, and returns a list of text edits to apply. - * Text edits must be non-overlapping and preferably in reverse-sorted order. - */ -export type RangeCodeFormatProvider = {| - formatCode: ( - editor: atom$TextEditor, - range: atom$Range, - ) => Promise>, - priority: number, - grammarScopes: Array, -|}; - -/** - * Formats the range specified, but returns the entire file (along with the new cursor position). - * Useful for less-flexible providers like clang-format. - */ -export type FileCodeFormatProvider = {| - formatEntireFile: ( - editor: atom$TextEditor, - range: atom$Range, - ) => Promise<{ - newCursor?: number, - formatted: string, - }>, - priority: number, - grammarScopes: Array, -|}; - -/** - * Formats around the given position, and returns a list of text edits to - * apply, similar to `formatCode`. The provider determines the exact - * range to format based on what's at that position. - * - * This will automatically triggered after every typing event. - */ -export type OnTypeCodeFormatProvider = {| - formatAtPosition: ( - editor: atom$TextEditor, - position: atom$Point, - triggerCharacter: string, - ) => Promise>, - priority: number, - grammarScopes: Array, -|}; - -/** - * Formats files after save events. - */ -export type OnSaveCodeFormatProvider = {| - formatOnSave: (editor: atom$TextEditor) => Promise>, - priority: number, - grammarScopes: Array, -|}; - -export type CodeFormatProvider = - | RangeCodeFormatProvider - | FileCodeFormatProvider - | OnTypeCodeFormatProvider - | OnSaveCodeFormatProvider; +'use strict'; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-code-format/spec/CodeFormatManager-spec.js b/modules/atom-ide-ui/pkg/atom-ide-code-format/spec/CodeFormatManager-spec.js index 51faa61e..0f7c284d 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-code-format/spec/CodeFormatManager-spec.js +++ b/modules/atom-ide-ui/pkg/atom-ide-code-format/spec/CodeFormatManager-spec.js @@ -1,89 +1,89 @@ -/** - * 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 - * @format - */ - -import {Range} from 'atom'; -import temp from 'temp'; -import * as config from '../lib/config'; -import CodeFormatManager from '../lib/CodeFormatManager'; - -describe('CodeFormatManager', () => { - let textEditor; - beforeEach(() => { - waitsForPromise(async () => { - temp.track(); - const file = temp.openSync(); - textEditor = await atom.workspace.open(file.path); - }); - }); +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + + + + + + + + + + + +var _atom = require('atom');var _temp; +function _load_temp() {return _temp = _interopRequireDefault(require('temp'));}var _config; +function _load_config() {return _config = _interopRequireWildcard(require('../lib/config'));}var _CodeFormatManager; +function _load_CodeFormatManager() {return _CodeFormatManager = _interopRequireDefault(require('../lib/CodeFormatManager'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */describe('CodeFormatManager', () => {let textEditor;beforeEach(() => {waitsForPromise((0, _asyncToGenerator.default)(function* () {(_temp || _load_temp()).default.track();const file = (_temp || _load_temp()).default.openSync();textEditor = yield atom.workspace.open(file.path);}));}); it('formats an editor on request', () => { - waitsForPromise(async () => { - const manager = new CodeFormatManager(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const manager = new (_CodeFormatManager || _load_CodeFormatManager()).default(); manager.addRangeProvider({ grammarScopes: ['text.plain.null-grammar'], priority: 1, - formatCode: () => - Promise.resolve([ + formatCode: function () {return ( + Promise.resolve([ { - oldRange: new Range([0, 0], [0, 3]), + oldRange: new _atom.Range([0, 0], [0, 3]), oldText: 'abc', - newText: 'def', - }, - ]), - }); + newText: 'def' }]));} }); + + + textEditor.setText('abc'); atom.commands.dispatch( - atom.views.getView(textEditor), - 'code-format:format-code', - ); - waitsFor(() => textEditor.getText() === 'def'); - }); + atom.views.getView(textEditor), + 'code-format:format-code'); + + waitsFor(function () {return textEditor.getText() === 'def';}); + })); }); it('format an editor using formatEntireFile', () => { - waitsForPromise(async () => { - const manager = new CodeFormatManager(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const manager = new (_CodeFormatManager || _load_CodeFormatManager()).default(); manager.addFileProvider({ grammarScopes: ['text.plain.null-grammar'], priority: 1, - formatEntireFile: () => Promise.resolve({formatted: 'ghi'}), - }); + formatEntireFile: function () {return Promise.resolve({ formatted: 'ghi' });} }); + textEditor.setText('abc'); atom.commands.dispatch( - atom.views.getView(textEditor), - 'code-format:format-code', - ); - waitsFor(() => textEditor.getText() === 'ghi'); - }); + atom.views.getView(textEditor), + 'code-format:format-code'); + + waitsFor(function () {return textEditor.getText() === 'ghi';}); + })); }); it('formats an editor on type', () => { - waitsForPromise(async () => { - spyOn(config, 'getFormatOnType').andReturn(true); - const manager = new CodeFormatManager(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + spyOn(_config || _load_config(), 'getFormatOnType').andReturn(true); + const manager = new (_CodeFormatManager || _load_CodeFormatManager()).default(); const provider = { grammarScopes: ['text.plain.null-grammar'], priority: 1, - formatAtPosition: () => - Promise.resolve([ + formatAtPosition: function () {return ( + Promise.resolve([ { - oldRange: new Range([0, 0], [0, 3]), + oldRange: new _atom.Range([0, 0], [0, 3]), oldText: 'abc', - newText: 'def', - }, - ]), - }; + newText: 'def' }]));} }; + + + const spy = spyOn(provider, 'formatAtPosition').andCallThrough(); manager.addOnTypeProvider(provider); @@ -92,67 +92,67 @@ describe('CodeFormatManager', () => { textEditor.insertText('b'); textEditor.insertText('c'); - waitsFor(() => textEditor.getText() === 'def'); - runs(() => { + waitsFor(function () {return textEditor.getText() === 'def';}); + runs(function () { // Debouncing should ensure only one format call. expect(spy.callCount).toBe(1); }); - }); + })); }); it('formats an editor on save', () => { - waitsForPromise(async () => { - spyOn(config, 'getFormatOnSave').andReturn(true); - const manager = new CodeFormatManager(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + spyOn(_config || _load_config(), 'getFormatOnSave').andReturn(true); + const manager = new (_CodeFormatManager || _load_CodeFormatManager()).default(); manager.addOnSaveProvider({ grammarScopes: ['text.plain.null-grammar'], priority: 1, - formatOnSave: () => - Promise.resolve([ + formatOnSave: function () {return ( + Promise.resolve([ { - oldRange: new Range([0, 0], [0, 3]), + oldRange: new _atom.Range([0, 0], [0, 3]), oldText: 'abc', - newText: 'def', - }, - ]), - }); + newText: 'def' }]));} }); + + + textEditor.setText('abc'); - await textEditor.save(); + yield textEditor.save(); expect(textEditor.getText()).toBe('def'); - }); + })); }); it('should still save on timeout', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { jasmine.Clock.useMock(); - spyOn(config, 'getFormatOnSave').andReturn(true); - const manager = new CodeFormatManager(); + spyOn(_config || _load_config(), 'getFormatOnSave').andReturn(true); + const manager = new (_CodeFormatManager || _load_CodeFormatManager()).default(); manager.addRangeProvider({ grammarScopes: ['text.plain.null-grammar'], priority: 1, - formatCode: () => new Promise(() => {}), - }); + formatCode: function () {return new Promise(function () {});} }); + const spy = spyOn(textEditor.getBuffer(), 'save').andCallThrough(); textEditor.save(); const savePromise = Promise.resolve(textEditor.save()); // The first save should be pushed through after the 2nd. - waitsFor(() => spy.callCount === 1); + waitsFor(function () {return spy.callCount === 1;}); - runs(() => { + runs(function () { jasmine.Clock.tick(3000); }); // Hitting the timeout will force the 2nd save through. - waitsFor(() => spy.callCount === 2); + waitsFor(function () {return spy.callCount === 2;}); // The real save should still go through. - waitsForPromise(() => savePromise); + waitsForPromise(function () {return savePromise;}); // Sanity check. - runs(() => expect(spy.callCount).toBe(2)); - }); + runs(function () {return expect(spy.callCount).toBe(2);}); + })); }); -}); +}); \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-code-highlight/lib/CodeHighlightManager.js b/modules/atom-ide-ui/pkg/atom-ide-code-highlight/lib/CodeHighlightManager.js index cb79ee91..5e06b77d 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-code-highlight/lib/CodeHighlightManager.js +++ b/modules/atom-ide-ui/pkg/atom-ide-code-highlight/lib/CodeHighlightManager.js @@ -1,145 +1,144 @@ -/** - * 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 - * @format - */ - -import type {CodeHighlightProvider} from './types'; - -import {getLogger} from 'log4js'; -import {Observable} from 'rxjs'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import {fastDebounce, toggle} from 'nuclide-commons/observable'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import ProviderRegistry from 'nuclide-commons-atom/ProviderRegistry'; -import {observeActiveEditorsDebounced} from 'nuclide-commons-atom/debounced'; - -const CURSOR_DELAY_MS = 250; -// Apply a much higher debounce to text changes to avoid disrupting the typing experience. -const CHANGE_TOGGLE_MS = 2500; - -export default class CodeHighlightManager { - _subscriptions: UniversalDisposable; - _providers: ProviderRegistry; - _markers: Array; - - constructor() { - this._providers = new ProviderRegistry(); +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _log4js; + + + + + + + + + + + + + +function _load_log4js() {return _log4js = require('log4js');} +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _event; +function _load_event() {return _event = require('nuclide-commons/event');}var _observable; +function _load_observable() {return _observable = require('nuclide-commons/observable');}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _ProviderRegistry; +function _load_ProviderRegistry() {return _ProviderRegistry = _interopRequireDefault(require('nuclide-commons-atom/ProviderRegistry'));}var _debounced; +function _load_debounced() {return _debounced = require('nuclide-commons-atom/debounced');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */const CURSOR_DELAY_MS = 250; // Apply a much higher debounce to text changes to avoid disrupting the typing experience. +const CHANGE_TOGGLE_MS = 2500;class CodeHighlightManager {constructor() { + this._providers = new (_ProviderRegistry || _load_ProviderRegistry()).default(); this._markers = []; - this._subscriptions = new UniversalDisposable(this._highlightEditors()); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(this._highlightEditors()); } - _highlightEditors(): rxjs$Subscription { - return observeActiveEditorsDebounced(0) - .do(() => this._destroyMarkers()) - .switchMap(editor => { - if (editor == null) { - return Observable.empty(); - } - const cursorPositions = observableFromSubscribeFunction( - editor.onDidChangeCursorPosition.bind(editor), - ) - .filter( - // If we're moving around inside highlighted ranges, that's fine. - event => - !this._isPositionInHighlightedRanges( - editor, - event.newBufferPosition, - ), - ) - .do(() => this._destroyMarkers()) // Immediately clear previous markers. - .let(fastDebounce(CURSOR_DELAY_MS)) - .startWith((null: any)) // Immediately kick off a highlight event. - .map(() => editor.getCursorBufferPosition()); - - // Changing text triggers a CHANGE_TOGGLE_MS period in which cursor changes are ignored. - // We'll model this as one stream that emits 'false' and another that debounces 'true's. - const changeEvents = observableFromSubscribeFunction( - editor.onDidChange.bind(editor), - ) - .do(() => this._destroyMarkers()) - .share(); - - const changeToggles = Observable.merge( - Observable.of(true), - changeEvents.mapTo(false), - changeEvents.let(fastDebounce(CHANGE_TOGGLE_MS)).mapTo(true), - ); - - const destroyEvents = observableFromSubscribeFunction( - editor.onDidDestroy.bind(editor), - ); - - return cursorPositions - .let(toggle(changeToggles)) - .switchMap(async position => { - return { - editor, - ranges: await this._getHighlightedRanges(editor, position), - }; - }) - .takeUntil(destroyEvents); - }) - .subscribe(({editor, ranges}) => { - if (ranges != null) { - this._highlightRanges(editor, ranges); - } - }); + _highlightEditors() {var _this = this; + return (0, (_debounced || _load_debounced()).observeActiveEditorsDebounced)(0). + do(() => this._destroyMarkers()). + switchMap(editor => { + if (editor == null) { + return _rxjsBundlesRxMinJs.Observable.empty(); + } + const cursorPositions = (0, (_event || _load_event()).observableFromSubscribeFunction)( + editor.onDidChangeCursorPosition.bind(editor)). + + filter( + // If we're moving around inside highlighted ranges, that's fine. + event => + !this._isPositionInHighlightedRanges( + editor, + event.newBufferPosition)). + + + do(() => this._destroyMarkers()) // Immediately clear previous markers. + .let((0, (_observable || _load_observable()).fastDebounce)(CURSOR_DELAY_MS)). + startWith(null) // Immediately kick off a highlight event. + .map(() => editor.getCursorBufferPosition()); + + // Changing text triggers a CHANGE_TOGGLE_MS period in which cursor changes are ignored. + // We'll model this as one stream that emits 'false' and another that debounces 'true's. + const changeEvents = (0, (_event || _load_event()).observableFromSubscribeFunction)( + editor.onDidChange.bind(editor)). + + do(() => this._destroyMarkers()). + share(); + + const changeToggles = _rxjsBundlesRxMinJs.Observable.merge( + _rxjsBundlesRxMinJs.Observable.of(true), + changeEvents.mapTo(false), + changeEvents.let((0, (_observable || _load_observable()).fastDebounce)(CHANGE_TOGGLE_MS)).mapTo(true)); + + + const destroyEvents = (0, (_event || _load_event()).observableFromSubscribeFunction)( + editor.onDidDestroy.bind(editor)); + + + return cursorPositions. + let((0, (_observable || _load_observable()).toggle)(changeToggles)). + switchMap((() => {var _ref = (0, _asyncToGenerator.default)(function* (position) { + return { + editor, + ranges: yield _this._getHighlightedRanges(editor, position) }; + + });return function (_x) {return _ref.apply(this, arguments);};})()). + takeUntil(destroyEvents); + }). + subscribe(({ editor, ranges }) => { + if (ranges != null) { + this._highlightRanges(editor, ranges); + } + }); } - async _getHighlightedRanges( - editor: atom$TextEditor, - position: atom$Point, - ): Promise> { - const provider = this._providers.getProviderForEditor(editor); - if (!provider) { - return null; - } - - try { - return await provider.highlight(editor, position); - } catch (e) { - getLogger('code-highlight').error('Error getting code highlights', e); - return null; - } + _getHighlightedRanges( + editor, + position) + {var _this2 = this;return (0, _asyncToGenerator.default)(function* () { + const provider = _this2._providers.getProviderForEditor(editor); + if (!provider) { + return null; + } + + try { + return yield provider.highlight(editor, position); + } catch (e) { + (0, (_log4js || _load_log4js()).getLogger)('code-highlight').error('Error getting code highlights', e); + return null; + }})(); } - _highlightRanges(editor: atom$TextEditor, ranges: Array): void { + _highlightRanges(editor, ranges) { this._destroyMarkers(); this._markers = ranges.map(range => editor.markBufferRange(range, {})); this._markers.forEach(marker => { editor.decorateMarker(marker, { type: 'highlight', - class: 'code-highlight-marker', - }); + class: 'code-highlight-marker' }); + }); } _isPositionInHighlightedRanges( - editor: atom$TextEditor, - position: atom$Point, - ): boolean { - return this._markers - .map(marker => marker.getBufferRange()) - .some(range => range.containsPoint(position)); + editor, + position) + { + return this._markers. + map(marker => marker.getBufferRange()). + some(range => range.containsPoint(position)); } - _destroyMarkers(): void { + _destroyMarkers() { this._markers.splice(0).forEach(marker => marker.destroy()); } - addProvider(provider: CodeHighlightProvider): IDisposable { + addProvider(provider) { return this._providers.addProvider(provider); } dispose() { this._subscriptions.dispose(); this._destroyMarkers(); - } -} + }}exports.default = CodeHighlightManager; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-code-highlight/lib/main.js b/modules/atom-ide-ui/pkg/atom-ide-code-highlight/lib/main.js index 6bdcf457..2e7af159 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-code-highlight/lib/main.js +++ b/modules/atom-ide-ui/pkg/atom-ide-code-highlight/lib/main.js @@ -1,34 +1,41 @@ -/** - * 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 - * @format - */ - -import type {CodeHighlightProvider} from './types'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import CodeHighlightManager from './CodeHighlightManager'; +'use strict';var _createPackage; + + + + + + + + + + + + + +function _load_createPackage() {return _createPackage = _interopRequireDefault(require('nuclide-commons-atom/createPackage'));}var _CodeHighlightManager; +function _load_CodeHighlightManager() {return _CodeHighlightManager = _interopRequireDefault(require('./CodeHighlightManager'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} class Activation { - _codeHighlightManager: CodeHighlightManager; + constructor() { - this._codeHighlightManager = new CodeHighlightManager(); + this._codeHighlightManager = new (_CodeHighlightManager || _load_CodeHighlightManager()).default(); } dispose() { this._codeHighlightManager.dispose(); } - addProvider(provider: CodeHighlightProvider): IDisposable { + addProvider(provider) { return this._codeHighlightManager.addProvider(provider); - } -} - -createPackage(module.exports, Activation); + }} /** + * 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. + * + * + * @format + */(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-code-highlight/lib/types.js b/modules/atom-ide-ui/pkg/atom-ide-code-highlight/lib/types.js index 167d70c1..9a390c31 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-code-highlight/lib/types.js +++ b/modules/atom-ide-ui/pkg/atom-ide-code-highlight/lib/types.js @@ -1,20 +1 @@ -/** - * 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 - * @format - */ - -export type CodeHighlightProvider = { - highlight( - editor: atom$TextEditor, - bufferPosition: atom$Point, - ): Promise>, - priority: number, - grammarScopes: Array, -}; +"use strict"; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-code-highlight/spec/CodeHighlightManager-spec.js b/modules/atom-ide-ui/pkg/atom-ide-code-highlight/spec/CodeHighlightManager-spec.js index 0e32da1a..63dfe6c1 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-code-highlight/spec/CodeHighlightManager-spec.js +++ b/modules/atom-ide-ui/pkg/atom-ide-code-highlight/spec/CodeHighlightManager-spec.js @@ -1,45 +1,45 @@ -/** - * 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 - * @format - */ - -import os from 'os'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {Point, Range} from 'atom'; - -import CodeHighlightManager from '../lib/CodeHighlightManager'; - -describe('CodeHighlightManager', () => { - let manager; - let provider; - let editor; - beforeEach(() => { - jasmine.useMockClock(); - waitsForPromise(async () => { - editor = await atom.workspace.open( - nuclideUri.join(os.tmpdir(), 'test.txt'), - ); +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + + + + + + + + + + + +var _os = _interopRequireDefault(require('os'));var _nuclideUri; +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));} +var _atom = require('atom');var _CodeHighlightManager; + +function _load_CodeHighlightManager() {return _CodeHighlightManager = _interopRequireDefault(require('../lib/CodeHighlightManager'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */describe('CodeHighlightManager', () => {let manager;let provider;let editor;beforeEach(() => {jasmine.useMockClock();waitsForPromise((0, _asyncToGenerator.default)(function* () {editor = yield atom.workspace.open((_nuclideUri || _load_nuclideUri()).default.join(_os.default.tmpdir(), 'test.txt')); + editor.setText('abc\ndef\nghi'); - manager = new CodeHighlightManager(); + manager = new (_CodeHighlightManager || _load_CodeHighlightManager()).default(); provider = { priority: 1, grammarScopes: ['text.plain.null-grammar'], - highlight: (_editor, position) => Promise.resolve([]), - }; + highlight: function (_editor, position) {return Promise.resolve([]);} }; + manager.addProvider(provider); - }); + })); }); it('updates highlights on cursor move', () => { - const ranges = [new Range([0, 0], [0, 3])]; + const ranges = [new _atom.Range([0, 0], [0, 3])]; const spy = spyOn(provider, 'highlight').andReturn(ranges); // Just opening the editor should trigger highlights. @@ -52,8 +52,8 @@ describe('CodeHighlightManager', () => { waitsFor(() => manager._markers.length === 1); runs(() => { - ranges[0] = new Range([1, 0], [1, 3]); - editor.setCursorBufferPosition(new Point(1, 0)); + ranges[0] = new _atom.Range([1, 0], [1, 3]); + editor.setCursorBufferPosition(new _atom.Point(1, 0)); advanceClock(300); // trigger debounce // Old markers should be cleared immediately. expect(manager._markers.length).toBe(0); @@ -64,13 +64,13 @@ describe('CodeHighlightManager', () => { // If we're still inside the range, don't fire a new event. runs(() => { - editor.setCursorBufferPosition(new Point(1, 1)); + editor.setCursorBufferPosition(new _atom.Point(1, 1)); expect(spy.callCount).toBe(2); }); waitsForPromise(() => - atom.workspace.open(nuclideUri.join(os.tmpdir(), 'test2.txt')), - ); + atom.workspace.open((_nuclideUri || _load_nuclideUri()).default.join(_os.default.tmpdir(), 'test2.txt'))); + runs(() => { // Opening a new editor should clear out old markers. @@ -80,7 +80,7 @@ describe('CodeHighlightManager', () => { }); it('updates highlights on change', () => { - const ranges = [new Range([0, 0], [0, 1])]; + const ranges = [new _atom.Range([0, 0], [0, 1])]; const spy = spyOn(provider, 'highlight').andReturn(ranges); runs(() => { @@ -99,4 +99,4 @@ describe('CodeHighlightManager', () => { expect(manager._markers.length).toBe(0); }); }); -}); +}); \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/lib/getCurrentExecutorId.js b/modules/atom-ide-ui/pkg/atom-ide-console/lib/getCurrentExecutorId.js index 37e662b8..123201f7 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/lib/getCurrentExecutorId.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/lib/getCurrentExecutorId.js @@ -1,22 +1,32 @@ -/** - * 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 - * @format - */ - -import type {AppState} from './types'; - -export default function getCurrentExecutorId(state: AppState): ?string { - let {currentExecutorId} = state; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default = + + + + + + + + + + + + + +getCurrentExecutorId;function getCurrentExecutorId(state) { + let { currentExecutorId } = state; if (currentExecutorId == null) { const firstExecutor = Array.from(state.executors.values())[0]; currentExecutorId = firstExecutor && firstExecutor.id; } return currentExecutorId; -} +} /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/lib/main.js b/modules/atom-ide-ui/pkg/atom-ide-console/lib/main.js index e2638466..e421d5b0 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/lib/main.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/lib/main.js @@ -1,114 +1,114 @@ -/** - * 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 - * @format - */ - -import type { - AppState, - ConsolePersistedState, - ConsoleService, - SourceInfo, - Message, - OutputProvider, - OutputProviderStatus, - OutputService, - Record, - RegisterExecutorFunction, - WatchEditorFunction, - Store, -} from './types'; -import type {CreatePasteFunction} from './types'; - -import {List} from 'immutable'; -import createPackage from 'nuclide-commons-atom/createPackage'; -import {destroyItemWhere} from 'nuclide-commons-atom/destroyItemWhere'; -import {Observable} from 'rxjs'; -import { - combineEpics, - createEpicMiddleware, -} from 'nuclide-commons/redux-observable'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import * as Actions from './redux/Actions'; -import * as Epics from './redux/Epics'; -import Reducers from './redux/Reducers'; -import {Console, WORKSPACE_VIEW_URI} from './ui/Console'; -import invariant from 'assert'; -import {applyMiddleware, createStore} from 'redux'; -import {makeToolbarButtonSpec} from 'nuclide-commons-ui/ToolbarUtils'; - -const MAXIMUM_SERIALIZED_MESSAGES_CONFIG = - 'atom-ide-console.maximumSerializedMessages'; -const MAXIMUM_SERIALIZED_HISTORY_CONFIG = - 'atom-ide-console.maximumSerializedHistory'; - -class Activation { - _disposables: UniversalDisposable; - _rawState: ?Object; - _store: Store; - - constructor(rawState: ?Object) { +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _immutable; + + + + + + + + + + + + + + + + + + + + + + + + + + + +function _load_immutable() {return _immutable = require('immutable');}var _createPackage; +function _load_createPackage() {return _createPackage = _interopRequireDefault(require('nuclide-commons-atom/createPackage'));}var _destroyItemWhere; +function _load_destroyItemWhere() {return _destroyItemWhere = require('nuclide-commons-atom/destroyItemWhere');} +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _reduxObservable; +function _load_reduxObservable() {return _reduxObservable = require('nuclide-commons/redux-observable');}var _event; + + + +function _load_event() {return _event = require('nuclide-commons/event');}var _featureConfig; +function _load_featureConfig() {return _featureConfig = _interopRequireDefault(require('nuclide-commons-atom/feature-config'));}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _Actions; +function _load_Actions() {return _Actions = _interopRequireWildcard(require('./redux/Actions'));}var _Epics; +function _load_Epics() {return _Epics = _interopRequireWildcard(require('./redux/Epics'));}var _Reducers; +function _load_Reducers() {return _Reducers = _interopRequireDefault(require('./redux/Reducers'));}var _Console; +function _load_Console() {return _Console = require('./ui/Console');}var _redux; + +function _load_redux() {return _redux = require('redux');}var _ToolbarUtils; +function _load_ToolbarUtils() {return _ToolbarUtils = require('nuclide-commons-ui/ToolbarUtils');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _objectWithoutProperties(obj, keys) {var target = {};for (var i in obj) {if (keys.indexOf(i) >= 0) continue;if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;target[i] = obj[i];}return target;} /** + * 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. + * + * + * @format + */const MAXIMUM_SERIALIZED_MESSAGES_CONFIG = 'atom-ide-console.maximumSerializedMessages';const MAXIMUM_SERIALIZED_HISTORY_CONFIG = 'atom-ide-console.maximumSerializedHistory';class Activation { + + constructor(rawState) { this._rawState = rawState; - this._disposables = new UniversalDisposable( - atom.contextMenu.add({ - '.console-record': [ - { - label: 'Copy Message', - command: 'console:copy-message', - }, - ], - }), - atom.commands.add('.console-record', 'console:copy-message', event => { - const el = event.target; - if (el == null || typeof el.innerText !== 'string') { - return; - } - atom.clipboard.write(el.innerText); - }), - atom.commands.add('atom-workspace', 'console:clear', () => - this._getStore().dispatch(Actions.clearRecords()), - ), - featureConfig.observe( - 'atom-ide-console.maximumMessageCount', - (maxMessageCount: any) => { - this._getStore().dispatch( - Actions.setMaxMessageCount(maxMessageCount), - ); - }, - ), - Observable.combineLatest( - observableFromSubscribeFunction(cb => - atom.config.observe('editor.fontSize', cb), - ), - featureConfig.observeAsStream('atom-ide-console.fontScale'), - (fontSize, fontScale) => fontSize * parseFloat(fontScale), - ) - .map(Actions.setFontSize) - .subscribe(this._store.dispatch), - this._registerCommandAndOpener(), - ); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default( + atom.contextMenu.add({ + '.console-record': [ + { + label: 'Copy Message', + command: 'console:copy-message' }] }), + + + + atom.commands.add('.console-record', 'console:copy-message', event => { + const el = event.target; + if (el == null || typeof el.innerText !== 'string') { + return; + } + atom.clipboard.write(el.innerText); + }), + atom.commands.add('atom-workspace', 'console:clear', () => + this._getStore().dispatch((_Actions || _load_Actions()).clearRecords())), + + (_featureConfig || _load_featureConfig()).default.observe( + 'atom-ide-console.maximumMessageCount', + maxMessageCount => { + this._getStore().dispatch( + (_Actions || _load_Actions()).setMaxMessageCount(maxMessageCount)); + + }), + + _rxjsBundlesRxMinJs.Observable.combineLatest( + (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => + atom.config.observe('editor.fontSize', cb)), + + (_featureConfig || _load_featureConfig()).default.observeAsStream('atom-ide-console.fontScale'), + (fontSize, fontScale) => fontSize * parseFloat(fontScale)). + + map((_Actions || _load_Actions()).setFontSize). + subscribe(this._store.dispatch), + this._registerCommandAndOpener()); + } - _getStore(): Store { + _getStore() { if (this._store == null) { const initialState = deserializeAppState(this._rawState); - const epics = Object.keys(Epics) - .map(k => Epics[k]) - .filter(epic => typeof epic === 'function'); - const rootEpic = combineEpics(...epics); - this._store = createStore( - Reducers, - initialState, - applyMiddleware(createEpicMiddleware(rootEpic)), - ); + const epics = Object.keys(_Epics || _load_Epics()). + map(k => (_Epics || _load_Epics())[k]). + filter(epic => typeof epic === 'function'); + const rootEpic = (0, (_reduxObservable || _load_reduxObservable()).combineEpics)(...epics); + this._store = (0, (_redux || _load_redux()).createStore)((_Reducers || _load_Reducers()).default, + + initialState, + (0, (_redux || _load_redux()).applyMiddleware)((0, (_reduxObservable || _load_reduxObservable()).createEpicMiddleware)(rootEpic))); + } return this._store; } @@ -117,95 +117,95 @@ class Activation { this._disposables.dispose(); } - consumeToolBar(getToolBar: toolbar$GetToolbar): void { + consumeToolBar(getToolBar) { const toolBar = getToolBar('nuclide-console'); toolBar.addButton( - makeToolbarButtonSpec({ - icon: 'terminal', - callback: 'console:toggle', - tooltip: 'Toggle Console', - priority: 700, - }), - ); + (0, (_ToolbarUtils || _load_ToolbarUtils()).makeToolbarButtonSpec)({ + icon: 'terminal', + callback: 'console:toggle', + tooltip: 'Toggle Console', + priority: 700 })); + + this._disposables.add(() => { toolBar.removeItems(); }); } - consumePasteProvider(provider: any): IDisposable { - const createPaste: CreatePasteFunction = provider.createPaste; - this._getStore().dispatch(Actions.setCreatePasteFunction(createPaste)); - return new UniversalDisposable(() => { + consumePasteProvider(provider) { + const createPaste = provider.createPaste; + this._getStore().dispatch((_Actions || _load_Actions()).setCreatePasteFunction(createPaste)); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { if (this._getStore().getState().createPasteFunction === createPaste) { - this._getStore().dispatch(Actions.setCreatePasteFunction(null)); + this._getStore().dispatch((_Actions || _load_Actions()).setCreatePasteFunction(null)); } }); } - consumeWatchEditor(watchEditor: WatchEditorFunction): IDisposable { - this._getStore().dispatch(Actions.setWatchEditor(watchEditor)); - return new UniversalDisposable(() => { + consumeWatchEditor(watchEditor) { + this._getStore().dispatch((_Actions || _load_Actions()).setWatchEditor(watchEditor)); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { if (this._getStore().getState().watchEditor === watchEditor) { - this._getStore().dispatch(Actions.setWatchEditor(null)); + this._getStore().dispatch((_Actions || _load_Actions()).setWatchEditor(null)); } }); } - provideAutocomplete(): atom$AutocompleteProvider { + provideAutocomplete() { const activation = this; return { labels: ['nuclide-console'], selector: '*', // Copies Chrome devtools and puts history suggestions at the bottom. suggestionPriority: -1, - async getSuggestions(request) { - // History provides suggestion only on exact match to current input. - const prefix = request.editor.getText(); - const history = activation._getStore().getState().history; - // Use a set to remove duplicates. - const seen = new Set(history); - return Array.from(seen) - .filter(text => text.startsWith(prefix)) - .map(text => ({text, replacementPrefix: prefix})); - }, - }; + getSuggestions(request) {return (0, _asyncToGenerator.default)(function* () { + // History provides suggestion only on exact match to current input. + const prefix = request.editor.getText(); + const history = activation._getStore().getState().history; + // Use a set to remove duplicates. + const seen = new Set(history); + return Array.from(seen). + filter(function (text) {return text.startsWith(prefix);}). + map(function (text) {return { text, replacementPrefix: prefix };});})(); + } }; + } - _registerCommandAndOpener(): UniversalDisposable { - return new UniversalDisposable( - atom.workspace.addOpener(uri => { - if (uri === WORKSPACE_VIEW_URI) { - return new Console({store: this._getStore()}); - } - }), - () => destroyItemWhere(item => item instanceof Console), - atom.commands.add('atom-workspace', 'console:toggle', () => { - atom.workspace.toggle(WORKSPACE_VIEW_URI); - }), - ); + _registerCommandAndOpener() { + return new (_UniversalDisposable || _load_UniversalDisposable()).default( + atom.workspace.addOpener(uri => { + if (uri === (_Console || _load_Console()).WORKSPACE_VIEW_URI) { + return new (_Console || _load_Console()).Console({ store: this._getStore() }); + } + }), + () => (0, (_destroyItemWhere || _load_destroyItemWhere()).destroyItemWhere)(item => item instanceof (_Console || _load_Console()).Console), + atom.commands.add('atom-workspace', 'console:toggle', () => { + atom.workspace.toggle((_Console || _load_Console()).WORKSPACE_VIEW_URI); + })); + } - deserializeConsole(state: ConsolePersistedState): Console { - return new Console({ + deserializeConsole(state) { + return new (_Console || _load_Console()).Console({ store: this._getStore(), initialFilterText: state.filterText, initialEnableRegExpFilter: state.enableRegExpFilter, - initialUnselectedSourceIds: state.unselectedSourceIds, - }); + initialUnselectedSourceIds: state.unselectedSourceIds }); + } /** - * This service provides a factory for creating a console object tied to a particular source. If - * the consumer wants to expose starting and stopping functionality through the Console UI (for - * example, to allow the user to decide when to start and stop tailing logs), they can include - * `start()` and `stop()` functions on the object they pass to the factory. - * - * When the factory is invoked, the source will be added to the Console UI's filter list. The - * factory returns a Disposable which should be disposed of when the source goes away (e.g. its - * package is disabled). This will remove the source from the Console UI's filter list (as long as - * there aren't any remaining messages from the source). - */ - provideConsole(): ConsoleService { + * This service provides a factory for creating a console object tied to a particular source. If + * the consumer wants to expose starting and stopping functionality through the Console UI (for + * example, to allow the user to decide when to start and stop tailing logs), they can include + * `start()` and `stop()` functions on the object they pass to the factory. + * + * When the factory is invoked, the source will be added to the Console UI's filter list. The + * factory returns a Disposable which should be disposed of when the source goes away (e.g. its + * package is disabled). This will remove the source from the Console UI's filter list (as long as + * there aren't any remaining messages from the source). + */ + provideConsole() { // Create a local, nullable reference so that the service consumers don't keep the Activation // instance in memory. let activation = this; @@ -213,65 +213,65 @@ class Activation { activation = null; }); - return (sourceInfo: SourceInfo) => { - invariant(activation != null); + return sourceInfo => {if (!( + activation != null)) {throw new Error('Invariant violation: "activation != null"');} let disposed; - activation._getStore().dispatch(Actions.registerSource(sourceInfo)); + activation._getStore().dispatch((_Actions || _load_Actions()).registerSource(sourceInfo)); const console = { // TODO: Update these to be (object: any, ...objects: Array): void. - log(object: string): void { - console.append({text: object, level: 'log'}); + log(object) { + console.append({ text: object, level: 'log' }); }, - warn(object: string): void { - console.append({text: object, level: 'warning'}); + warn(object) { + console.append({ text: object, level: 'warning' }); }, - error(object: string): void { - console.append({text: object, level: 'error'}); + error(object) { + console.append({ text: object, level: 'error' }); }, - info(object: string): void { - console.append({text: object, level: 'info'}); + info(object) { + console.append({ text: object, level: 'info' }); }, - success(object: string): void { - console.append({text: object, level: 'success'}); + success(object) { + console.append({ text: object, level: 'success' }); }, - append(message: Message): void { - invariant(activation != null && !disposed); + append(message) {if (!( + activation != null && !disposed)) {throw new Error('Invariant violation: "activation != null && !disposed"');} activation._getStore().dispatch( - Actions.recordReceived({ - text: message.text, - level: message.level, - format: message.format, - data: message.data, - tags: message.tags, - scopeName: message.scopeName, - sourceId: sourceInfo.id, - kind: message.kind || 'message', - timestamp: new Date(), // TODO: Allow this to come with the message? - repeatCount: 1, - }), - ); + (_Actions || _load_Actions()).recordReceived({ + text: message.text, + level: message.level, + format: message.format, + data: message.data, + tags: message.tags, + scopeName: message.scopeName, + sourceId: sourceInfo.id, + kind: message.kind || 'message', + timestamp: new Date(), // TODO: Allow this to come with the message? + repeatCount: 1 })); + + }, - setStatus(status: OutputProviderStatus): void { - invariant(activation != null && !disposed); - activation - ._getStore() - .dispatch(Actions.updateStatus(sourceInfo.id, status)); + setStatus(status) {if (!( + activation != null && !disposed)) {throw new Error('Invariant violation: "activation != null && !disposed"');} + activation. + _getStore(). + dispatch((_Actions || _load_Actions()).updateStatus(sourceInfo.id, status)); }, - dispose(): void { - invariant(activation != null); + dispose() {if (!( + activation != null)) {throw new Error('Invariant violation: "activation != null"');} if (!disposed) { disposed = true; - activation - ._getStore() - .dispatch(Actions.removeSource(sourceInfo.id)); + activation. + _getStore(). + dispatch((_Actions || _load_Actions()).removeSource(sourceInfo.id)); } - }, - }; + } }; + return console; }; } - provideOutputService(): OutputService { + provideOutputService() { // Create a local, nullable reference so that the service consumers don't keep the Activation // instance in memory. let activation = this; @@ -280,23 +280,23 @@ class Activation { }); return { - registerOutputProvider(outputProvider: OutputProvider): IDisposable { - invariant(activation != null, 'Output service used after deactivation'); - activation - ._getStore() - .dispatch(Actions.registerOutputProvider(outputProvider)); - return new UniversalDisposable(() => { + registerOutputProvider(outputProvider) {if (!( + activation != null)) {throw new Error('Output service used after deactivation');} + activation. + _getStore(). + dispatch((_Actions || _load_Actions()).registerOutputProvider(outputProvider)); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { if (activation != null) { - activation - ._getStore() - .dispatch(Actions.unregisterOutputProvider(outputProvider)); + activation. + _getStore(). + dispatch((_Actions || _load_Actions()).unregisterOutputProvider(outputProvider)); } }); - }, - }; + } }; + } - provideRegisterExecutor(): RegisterExecutorFunction { + provideRegisterExecutor() { // Create a local, nullable reference so that the service consumers don't keep the Activation // instance in memory. let activation = this; @@ -304,72 +304,72 @@ class Activation { activation = null; }); - return executor => { - invariant( - activation != null, - 'Executor registration attempted after deactivation', - ); - activation._getStore().dispatch(Actions.registerExecutor(executor)); - return new UniversalDisposable(() => { + return executor => {if (!( + + activation != null)) {throw new Error( + 'Executor registration attempted after deactivation');} + + activation._getStore().dispatch((_Actions || _load_Actions()).registerExecutor(executor)); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { if (activation != null) { - activation._getStore().dispatch(Actions.unregisterExecutor(executor)); + activation._getStore().dispatch((_Actions || _load_Actions()).unregisterExecutor(executor)); } }); }; } - serialize(): Object { + serialize() { if (this._store == null) { return {}; } - const maximumSerializedMessages: number = (featureConfig.get( - MAXIMUM_SERIALIZED_MESSAGES_CONFIG, - ): any); - const maximumSerializedHistory: number = (featureConfig.get( - MAXIMUM_SERIALIZED_HISTORY_CONFIG, - ): any); + const maximumSerializedMessages = (_featureConfig || _load_featureConfig()).default.get( + MAXIMUM_SERIALIZED_MESSAGES_CONFIG); + + const maximumSerializedHistory = (_featureConfig || _load_featureConfig()).default.get( + MAXIMUM_SERIALIZED_HISTORY_CONFIG); + return { - records: this._store - .getState() - .records.slice(-maximumSerializedMessages) - .toArray() - .map(record => { - // `Executor` is not serializable. Make sure to remove it first. - const {executor, ...rest} = record; - return rest; - }), - history: this._store.getState().history.slice(-maximumSerializedHistory), - }; - } -} + records: this._store. + getState(). + records.slice(-maximumSerializedMessages). + toArray(). + map(record => { + // `Executor` is not serializable. Make sure to remove it first. + const { executor } = record,rest = _objectWithoutProperties(record, ['executor']); + return rest; + }), + history: this._store.getState().history.slice(-maximumSerializedHistory) }; + + }} -function deserializeAppState(rawState: ?Object): AppState { + +function deserializeAppState(rawState) { return { executors: new Map(), createPasteFunction: null, currentExecutorId: null, records: - rawState && rawState.records - ? List(rawState.records.map(deserializeRecord)) - : List(), + rawState && rawState.records ? + (0, (_immutable || _load_immutable()).List)(rawState.records.map(deserializeRecord)) : + (0, (_immutable || _load_immutable()).List)(), history: rawState && rawState.history ? rawState.history : [], providers: new Map(), providerStatuses: new Map(), // This value will be replaced with the value form the config. We just use `POSITIVE_INFINITY` // here to conform to the AppState type defintion. - maxMessageCount: Number.POSITIVE_INFINITY, - }; + maxMessageCount: Number.POSITIVE_INFINITY }; + } -function deserializeRecord(record: Object): Record { - return { - ...record, - timestamp: parseDate(record.timestamp) || new Date(0), - }; +function deserializeRecord(record) { + return Object.assign({}, + record, { + timestamp: parseDate(record.timestamp) || new Date(0) }); + } -function parseDate(raw: ?string): ?Date { +function parseDate(raw) { if (raw == null) { return null; } @@ -377,4 +377,4 @@ function parseDate(raw: ?string): ?Date { return isNaN(date.getTime()) ? null : date; } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/lib/parseText.js b/modules/atom-ide-ui/pkg/atom-ide-console/lib/parseText.js index 98883aff..48373e80 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/lib/parseText.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/lib/parseText.js @@ -1,78 +1,78 @@ -/** - * 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 - * @format - */ - -import * as React from 'react'; -import featureConfig from 'nuclide-commons-atom/feature-config'; - -import {URL_REGEX} from 'nuclide-commons/string'; -const DIFF_PATTERN = '\\b[dD][1-9][0-9]{5,}\\b'; -const TASK_PATTERN = '\\b[tT]\\d+\\b'; - -/** - * This does NOT contain a pattern to match file references. It's difficult to write such a pattern - * that matches all and only file references, and it's even worse when you add remote development - * into the mix. The upshot is that it adds more confusion than convenience, and a proper solution - * will require moving to a more robust parsing and rendering approach entirely. - */ -const CLICKABLE_PATTERNS = `(${DIFF_PATTERN})|(${TASK_PATTERN})|(${ - URL_REGEX.source -})`; -const CLICKABLE_RE = new RegExp(CLICKABLE_PATTERNS, 'g'); - -function toString(value: mixed): string { - return typeof value === 'string' ? value : ''; -} - -/** - * Parse special entities into links. In the future, it would be great to add a service so that we - * could add new clickable things and to allow providers to mark specific ranges as links to things - * that only they can know (e.g. relative paths output in BUCK messages). For now, however, we'll - * just use some pattern settings and hardcode the patterns we care about. - */ -export default function parseText( - text: string, -): Array> { - const chunks = []; - let lastIndex = 0; - let index = 0; - while (true) { - const match = CLICKABLE_RE.exec(text); - if (match == null) { - break; - } +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default = + + + + + + + + + + + + + + + + + + + + - const matchedText = match[0]; - // Add all the text since our last match. - chunks.push( - text.slice(lastIndex, CLICKABLE_RE.lastIndex - matchedText.length), - ); - lastIndex = CLICKABLE_RE.lastIndex; - let href; - let handleOnClick; + + + + + + + + + + + + + + + + +parseText;var _react = _interopRequireWildcard(require('react'));var _featureConfig;function _load_featureConfig() {return _featureConfig = _interopRequireDefault(require('nuclide-commons-atom/feature-config'));}var _string;function _load_string() {return _string = require('nuclide-commons/string');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}const DIFF_PATTERN = '\\b[dD][1-9][0-9]{5,}\\b'; /** + * 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. + * + * + * @format + */const TASK_PATTERN = '\\b[tT]\\d+\\b'; /** + * This does NOT contain a pattern to match file references. It's difficult to write such a pattern + * that matches all and only file references, and it's even worse when you add remote development + * into the mix. The upshot is that it adds more confusion than convenience, and a proper solution + * will require moving to a more robust parsing and rendering approach entirely. + */const CLICKABLE_PATTERNS = `(${DIFF_PATTERN})|(${TASK_PATTERN})|(${(_string || _load_string()).URL_REGEX.source})`;const CLICKABLE_RE = new RegExp(CLICKABLE_PATTERNS, 'g');function toString(value) {return typeof value === 'string' ? value : '';} /** + * Parse special entities into links. In the future, it would be great to add a service so that we + * could add new clickable things and to allow providers to mark specific ranges as links to things + * that only they can know (e.g. relative paths output in BUCK messages). For now, however, we'll + * just use some pattern settings and hardcode the patterns we care about. + */function parseText(text) {const chunks = [];let lastIndex = 0;let index = 0;while (true) {const match = CLICKABLE_RE.exec(text);if (match == null) {break;}const matchedText = match[0]; // Add all the text since our last match. + chunks.push(text.slice(lastIndex, CLICKABLE_RE.lastIndex - matchedText.length));lastIndex = CLICKABLE_RE.lastIndex;let href;let handleOnClick; if (match[1] != null) { // It's a diff const url = toString( - featureConfig.get('atom-ide-console.diffUrlPattern'), - ); + (_featureConfig || _load_featureConfig()).default.get('atom-ide-console.diffUrlPattern')); + if (url !== '') { href = url.replace('%s', matchedText); } } else if (match[2] != null) { // It's a task const url = toString( - featureConfig.get('atom-ide-console.taskUrlPattern'), - ); + (_featureConfig || _load_featureConfig()).default.get('atom-ide-console.taskUrlPattern')); + if (url !== '') { href = url.replace('%s', matchedText.slice(1)); } @@ -82,19 +82,19 @@ export default function parseText( } chunks.push( - // flowlint-next-line sketchy-null-string:off - href ? ( - - {matchedText} - - ) : ( - matchedText - ), - ); + // flowlint-next-line sketchy-null-string:off + href ? + _react.createElement('a', { + key: `r${index}`, + href: href, + target: '_blank', + onClick: handleOnClick }, + matchedText) : + + + matchedText); + + index++; } @@ -103,4 +103,4 @@ export default function parseText( chunks.push(text.slice(lastIndex)); return chunks; -} +} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/lib/recordsChanged.js b/modules/atom-ide-ui/pkg/atom-ide-console/lib/recordsChanged.js index ab27f72a..cbaa04c7 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/lib/recordsChanged.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/lib/recordsChanged.js @@ -1,30 +1,34 @@ -/** - * 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 - * @format - */ - -import type {DisplayableRecord} from './types'; - -import idx from 'idx'; - -/** - * Check to see if the records have changed. This is optimized to take advantage of the knowledge - * knowledge that record lists are only ever appended. - */ -export default function recordsChanged( - a: Array, - b: Array, -): boolean { - return ( - a.length !== b.length || idx(last(a), _ => _.id) !== idx(last(b), _ => _.id) - ); -} - -const last = arr => arr[arr.length - 1]; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default = + + + + + + + + + + + + + + + + + + + +recordsChanged;var _idx;function _load_idx() {return _idx = _interopRequireDefault(require('idx'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * Check to see if the records have changed. This is optimized to take advantage of the knowledge + * knowledge that record lists are only ever appended. + */ /** + * 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. + * + * + * @format + */function recordsChanged(a, b) {var _ref, _ref2;return a.length !== b.length || ((_ref = last(a)) != null ? _ref.id : _ref) !== ((_ref2 = last(b)) != null ? _ref2.id : _ref2);}const last = arr => arr[arr.length - 1]; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/lib/redux/Actions.js b/modules/atom-ide-ui/pkg/atom-ide-console/lib/redux/Actions.js index 66bf0761..1f6db7c1 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/lib/redux/Actions.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/lib/redux/Actions.js @@ -1,171 +1,182 @@ -/** - * 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 - * @format - */ - -import type { - Action, - Executor, - OutputProvider, - OutputProviderStatus, - Record, - RecordProvider, - SourceInfo, - WatchEditorFunction, -} from '../types'; - -import type {CreatePasteFunction} from '../types'; - -export const CLEAR_RECORDS = 'CLEAR_RECORDS'; -export const SET_CREATE_PASTE_FUNCTION = 'SET_CREATE_PASTE_FUNCTION'; -export const SET_WATCH_EDITOR_FUNCTION = 'SET_WATCH_EDITOR_FUNCTION'; -export const REGISTER_EXECUTOR = 'REGISTER_EXECUTOR'; -export const EXECUTE = 'EXECUTE'; -export const REGISTER_RECORD_PROVIDER = 'REGISTER_RECORD_PROVIDER'; -export const SELECT_EXECUTOR = 'SELECT_EXECUTOR'; -export const SET_MAX_MESSAGE_COUNT = 'SET_MAX_MESSAGE_COUNT'; -export const RECORD_RECEIVED = 'RECORD_RECEIVED'; -export const REGISTER_SOURCE = 'REGISTER_SOURCE'; -export const REMOVE_SOURCE = 'REMOVE_SOURCE'; -export const UPDATE_STATUS = 'UPDATE_STATUS'; -export const SET_FONT_SIZE = 'SET_FONT_SIZE'; - -export function clearRecords(): Action { - return {type: CLEAR_RECORDS}; -} - -export function recordReceived(record: Record): Action { - return { - type: RECORD_RECEIVED, - payload: {record}, - }; -} - -export function registerExecutor(executor: Executor): Action { - return { - type: REGISTER_EXECUTOR, - payload: {executor}, - }; -} - -export function execute(code: string): Action { - return { - type: EXECUTE, - payload: {code}, - }; -} - -export function registerOutputProvider(outputProvider: OutputProvider): Action { - // Transform the messages into actions and merge them into the action stream. +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +clearRecords = clearRecords;exports. + + + +recordReceived = recordReceived;exports. + + + + + + +registerExecutor = registerExecutor;exports. + + + + + + +execute = execute;exports. + + + + + + +registerOutputProvider = registerOutputProvider;exports. + + + + + + + + + + + + + + + + + + + + + + + +registerRecordProvider = registerRecordProvider;exports. + + + + + + +registerSource = registerSource;exports. + + + + + + +unregisterRecordProvider = unregisterRecordProvider;exports. + + + + + +unregisterOutputProvider = unregisterOutputProvider;exports. + + + + + +selectExecutor = selectExecutor;exports. + + + + + + +setMaxMessageCount = setMaxMessageCount;exports. + + + + + + +removeSource = removeSource;exports. + + + + + + +unregisterExecutor = unregisterExecutor;exports. + + + +updateStatus = updateStatus;exports. + + + + + + + + + +setCreatePasteFunction = setCreatePasteFunction;exports. + + + + + + + + +setWatchEditor = setWatchEditor;exports. + + + + + + +setFontSize = setFontSize; /** + * 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. + * + * + * @format + */const CLEAR_RECORDS = exports.CLEAR_RECORDS = 'CLEAR_RECORDS';const SET_CREATE_PASTE_FUNCTION = exports.SET_CREATE_PASTE_FUNCTION = 'SET_CREATE_PASTE_FUNCTION';const SET_WATCH_EDITOR_FUNCTION = exports.SET_WATCH_EDITOR_FUNCTION = 'SET_WATCH_EDITOR_FUNCTION';const REGISTER_EXECUTOR = exports.REGISTER_EXECUTOR = 'REGISTER_EXECUTOR';const EXECUTE = exports.EXECUTE = 'EXECUTE';const REGISTER_RECORD_PROVIDER = exports.REGISTER_RECORD_PROVIDER = 'REGISTER_RECORD_PROVIDER';const SELECT_EXECUTOR = exports.SELECT_EXECUTOR = 'SELECT_EXECUTOR';const SET_MAX_MESSAGE_COUNT = exports.SET_MAX_MESSAGE_COUNT = 'SET_MAX_MESSAGE_COUNT';const RECORD_RECEIVED = exports.RECORD_RECEIVED = 'RECORD_RECEIVED';const REGISTER_SOURCE = exports.REGISTER_SOURCE = 'REGISTER_SOURCE';const REMOVE_SOURCE = exports.REMOVE_SOURCE = 'REMOVE_SOURCE';const UPDATE_STATUS = exports.UPDATE_STATUS = 'UPDATE_STATUS';const SET_FONT_SIZE = exports.SET_FONT_SIZE = 'SET_FONT_SIZE';function clearRecords() {return { type: CLEAR_RECORDS };}function recordReceived(record) {return { type: RECORD_RECEIVED, payload: { record } };}function registerExecutor(executor) {return { type: REGISTER_EXECUTOR, payload: { executor } };}function execute(code) {return { type: EXECUTE, payload: { code } };}function registerOutputProvider(outputProvider) {// Transform the messages into actions and merge them into the action stream. // TODO: Add enabling/disabling of registered source and only subscribe when enabled. That // way, we won't trigger cold observer side-effects when we don't need the results. - return registerRecordProvider({ - ...outputProvider, - records: outputProvider.messages.map(message => ({ - // We duplicate the properties here instead of using spread because Flow (currently) has some + return registerRecordProvider(Object.assign({}, outputProvider, { records: outputProvider.messages.map(message => ({ // We duplicate the properties here instead of using spread because Flow (currently) has some // issues with spread. - text: message.text, - level: message.level, - data: message.data, - tags: message.tags, - repeatCount: 1, - - kind: 'message', - sourceId: outputProvider.id, - scopeName: null, - // Eventually, we'll want to allow providers to specify custom timestamps for records. - timestamp: new Date(), - })), - }); -} - -export function registerRecordProvider(recordProvider: RecordProvider): Action { - return { - type: REGISTER_RECORD_PROVIDER, - payload: {recordProvider}, - }; -} - -export function registerSource(source: SourceInfo): Action { - return { - type: REGISTER_SOURCE, - payload: {source}, - }; -} - -export function unregisterRecordProvider( - recordProvider: RecordProvider, -): Action { - return removeSource(recordProvider.id); -} - -export function unregisterOutputProvider( - outputProvider: OutputProvider, -): Action { - return removeSource(outputProvider.id); -} - -export function selectExecutor(executorId: string): Action { - return { - type: SELECT_EXECUTOR, - payload: {executorId}, - }; -} - -export function setMaxMessageCount(maxMessageCount: number): Action { - return { - type: SET_MAX_MESSAGE_COUNT, - payload: {maxMessageCount}, - }; -} - -export function removeSource(sourceId: string): Action { - return { - type: REMOVE_SOURCE, - payload: {sourceId}, - }; -} - -export function unregisterExecutor(executor: Executor): Action { - return removeSource(executor.id); -} - -export function updateStatus( - providerId: string, - status: OutputProviderStatus, -): Action { - return { - type: UPDATE_STATUS, - payload: {providerId, status}, - }; -} - -export function setCreatePasteFunction( - createPasteFunction: ?CreatePasteFunction, -): Action { - return { - type: SET_CREATE_PASTE_FUNCTION, - payload: {createPasteFunction}, - }; -} - -export function setWatchEditor(watchEditor: ?WatchEditorFunction): Action { - return { - type: SET_WATCH_EDITOR_FUNCTION, - payload: {watchEditor}, - }; -} - -export function setFontSize(fontSize: number): Action { - return { - type: SET_FONT_SIZE, - payload: {fontSize}, - }; -} + text: message.text, level: message.level, data: message.data, tags: message.tags, repeatCount: 1, kind: 'message', sourceId: outputProvider.id, scopeName: null, // Eventually, we'll want to allow providers to specify custom timestamps for records. + timestamp: new Date() })) }));}function registerRecordProvider(recordProvider) {return { type: REGISTER_RECORD_PROVIDER, payload: { recordProvider } };}function registerSource(source) {return { type: REGISTER_SOURCE, payload: { source } };}function unregisterRecordProvider(recordProvider) {return removeSource(recordProvider.id);}function unregisterOutputProvider(outputProvider) {return removeSource(outputProvider.id);}function selectExecutor(executorId) {return { type: SELECT_EXECUTOR, payload: { executorId } };}function setMaxMessageCount(maxMessageCount) {return { type: SET_MAX_MESSAGE_COUNT, payload: { maxMessageCount } };}function removeSource(sourceId) {return { type: REMOVE_SOURCE, payload: { sourceId } };}function unregisterExecutor(executor) {return removeSource(executor.id);}function updateStatus(providerId, status) {return { type: UPDATE_STATUS, payload: { providerId, status } };}function setCreatePasteFunction(createPasteFunction) {return { type: SET_CREATE_PASTE_FUNCTION, payload: { createPasteFunction } };}function setWatchEditor(watchEditor) {return { type: SET_WATCH_EDITOR_FUNCTION, payload: { watchEditor } };}function setFontSize(fontSize) {return { type: SET_FONT_SIZE, payload: { fontSize } };} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/lib/redux/Epics.js b/modules/atom-ide-ui/pkg/atom-ide-console/lib/redux/Epics.js index b12ea726..40aea210 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/lib/redux/Epics.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/lib/redux/Epics.js @@ -1,137 +1,137 @@ -/** - * 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 - * @format - */ - -import type {Action, Store} from '../types'; -import type {ActionsObservable} from 'nuclide-commons/redux-observable'; - -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import * as Actions from './Actions'; -import getCurrentExecutorId from '../getCurrentExecutorId'; -import invariant from 'assert'; -import {Observable} from 'rxjs'; -import analytics from 'nuclide-commons/analytics'; - -/** - * Register a record provider for every executor. - */ -export function registerExecutorEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions.ofType(Actions.REGISTER_EXECUTOR).map(action => { - invariant(action.type === Actions.REGISTER_EXECUTOR); - const {executor} = action.payload; - return Actions.registerRecordProvider({ - id: executor.id, - // $FlowIssue: Flow is having some trouble with the spread here. - records: executor.output.map(message => ({ - ...message, - kind: 'response', - sourceId: executor.id, - scopeName: null, // The output won't be in the language's grammar. +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + + + + + + + + + + + + +registerExecutorEpic = registerExecutorEpic;exports. + + + + + + + + + + + + + + + + + + + + + + + + + +executeEpic = executeEpic;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +trackEpic = trackEpic;exports. + + + + + + + + + + +registerRecordProviderEpic = registerRecordProviderEpic;var _event;function _load_event() {return _event = require('nuclide-commons/event');}var _Actions;function _load_Actions() {return _Actions = _interopRequireWildcard(require('./Actions'));}var _getCurrentExecutorId;function _load_getCurrentExecutorId() {return _getCurrentExecutorId = _interopRequireDefault(require('../getCurrentExecutorId'));}var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _analytics;function _load_analytics() {return _analytics = _interopRequireDefault(require('nuclide-commons/analytics'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} /** + * Register a record provider for every executor. + */function registerExecutorEpic(actions, store) {return actions.ofType((_Actions || _load_Actions()).REGISTER_EXECUTOR).map(action => {if (!(action.type === (_Actions || _load_Actions()).REGISTER_EXECUTOR)) {throw new Error('Invariant violation: "action.type === Actions.REGISTER_EXECUTOR"');}const { executor } = action.payload;return (_Actions || _load_Actions()).registerRecordProvider({ id: executor.id, // $FlowIssue: Flow is having some trouble with the spread here. + records: executor.output.map(message => Object.assign({}, message, { kind: 'response', sourceId: executor.id, scopeName: null, // The output won't be in the language's grammar. // Eventually, we'll want to allow providers to specify custom timestamps for records. - timestamp: new Date(), - executor, - })), - }); - }); -} - -/** - * Execute the provided code using the current executor. - */ -export function executeEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions.ofType(Actions.EXECUTE).flatMap(action => { - invariant(action.type === Actions.EXECUTE); - const {code} = action.payload; - const currentExecutorId = getCurrentExecutorId(store.getState()); - // flowlint-next-line sketchy-null-string:off - invariant(currentExecutorId); - - const executor = store.getState().executors.get(currentExecutorId); - invariant(executor != null); - - // TODO: Is this the best way to do this? Might want to go through nuclide-executors and have + timestamp: new Date(), executor })) });});} /** + * Execute the provided code using the current executor. + */ /** + * 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. + * + * + * @format + */function executeEpic(actions, store) {return actions.ofType((_Actions || _load_Actions()).EXECUTE).flatMap(action => {if (!(action.type === (_Actions || _load_Actions()).EXECUTE)) {throw new Error('Invariant violation: "action.type === Actions.EXECUTE"');}const { code } = action.payload;const currentExecutorId = (0, (_getCurrentExecutorId || _load_getCurrentExecutorId()).default)(store.getState()); // flowlint-next-line sketchy-null-string:off + if (!currentExecutorId) {throw new Error('Invariant violation: "currentExecutorId"');}const executor = store.getState().executors.get(currentExecutorId);if (!(executor != null)) {throw new Error('Invariant violation: "executor != null"');} // TODO: Is this the best way to do this? Might want to go through nuclide-executors and have // that register output sources? - return ( - Observable.of( - Actions.recordReceived({ - // Eventually, we'll want to allow providers to specify custom timestamps for records. - timestamp: new Date(), - sourceId: currentExecutorId, - kind: 'request', - level: 'log', - text: code, - scopeName: executor.scopeName, - data: null, - repeatCount: 1, - }), - ) - // Execute the code as a side-effect. - .finally(() => { - executor.send(code); - }) - ); - }); -} - -export function trackEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions - .ofType(Actions.EXECUTE) - .map(action => ({type: 'console:execute'})) - .do(analytics.trackEvent) - .ignoreElements(); -} - -export function registerRecordProviderEpic( - actions: ActionsObservable, - store: Store, -): Observable { - return actions.ofType(Actions.REGISTER_RECORD_PROVIDER).flatMap(action => { - invariant(action.type === Actions.REGISTER_RECORD_PROVIDER); - const {recordProvider} = action.payload; - - // Transform the messages into actions and merge them into the action stream. + return _rxjsBundlesRxMinJs.Observable.of((_Actions || _load_Actions()).recordReceived({ // Eventually, we'll want to allow providers to specify custom timestamps for records. + timestamp: new Date(), sourceId: currentExecutorId, kind: 'request', level: 'log', text: code, scopeName: executor.scopeName, data: null, repeatCount: 1 })) // Execute the code as a side-effect. + .finally(() => {executor.send(code);});});}function trackEpic(actions, store) {return actions.ofType((_Actions || _load_Actions()).EXECUTE).map(action => ({ type: 'console:execute' })).do((_analytics || _load_analytics()).default.trackEvent).ignoreElements();}function registerRecordProviderEpic(actions, store) {return actions.ofType((_Actions || _load_Actions()).REGISTER_RECORD_PROVIDER).flatMap(action => {if (!(action.type === (_Actions || _load_Actions()).REGISTER_RECORD_PROVIDER)) {throw new Error('Invariant violation: "action.type === Actions.REGISTER_RECORD_PROVIDER"');}const { recordProvider } = action.payload; // Transform the messages into actions and merge them into the action stream. // TODO: Add enabling/disabling of registered source and only subscribe when enabled. That // way, we won't trigger cold observer side-effects when we don't need the results. - const messageActions = recordProvider.records.map(Actions.recordReceived); - - // TODO: Can this be delayed until sometime after registration? - const statusActions = - typeof recordProvider.observeStatus === 'function' - ? observableFromSubscribeFunction(recordProvider.observeStatus).map( - status => Actions.updateStatus(recordProvider.id, status), - ) - : Observable.empty(); - - const unregisteredEvents = actions - .ofType(Actions.REMOVE_SOURCE) - .filter(a => { - invariant(a.type === Actions.REMOVE_SOURCE); - return a.payload.sourceId === recordProvider.id; - }); - - return Observable.merge( - Observable.of( - Actions.registerSource({...recordProvider, name: recordProvider.id}), - ), - messageActions, - statusActions, - ).takeUntil(unregisteredEvents); + const messageActions = recordProvider.records.map((_Actions || _load_Actions()).recordReceived); // TODO: Can this be delayed until sometime after registration? + const statusActions = typeof recordProvider.observeStatus === 'function' ? (0, (_event || _load_event()).observableFromSubscribeFunction)(recordProvider.observeStatus).map(status => (_Actions || _load_Actions()).updateStatus(recordProvider.id, status)) : _rxjsBundlesRxMinJs.Observable.empty();const unregisteredEvents = actions.ofType((_Actions || _load_Actions()).REMOVE_SOURCE).filter(a => {if (!(a.type === (_Actions || _load_Actions()).REMOVE_SOURCE)) {throw new Error('Invariant violation: "a.type === Actions.REMOVE_SOURCE"');}return a.payload.sourceId === recordProvider.id;}); + + return _rxjsBundlesRxMinJs.Observable.merge( + _rxjsBundlesRxMinJs.Observable.of( + (_Actions || _load_Actions()).registerSource(Object.assign({}, recordProvider, { name: recordProvider.id }))), + + messageActions, + statusActions). + takeUntil(unregisteredEvents); }); -} +} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/lib/redux/Reducers.js b/modules/atom-ide-ui/pkg/atom-ide-console/lib/redux/Reducers.js index 68afa00d..9d94a23b 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/lib/redux/Reducers.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/lib/redux/Reducers.js @@ -1,196 +1,196 @@ -/** - * 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 - * @format - */ - -import type {Action, AppState, Record} from '../types'; - -import {List} from 'immutable'; -import {arrayEqual} from 'nuclide-commons/collection'; -import * as Actions from './Actions'; - -const RECORD_PROPERTIES_TO_COMPARE = [ - 'text', - 'level', - 'format', - 'scopeName', - 'sourceId', - 'kind', -]; - -function shouldAccumulateRecordCount( - recordA: Record, - recordB: Record, -): boolean { - if ( - String(recordA.sourceId) - .toLowerCase() - .includes('debugger') || - String(recordB.sourceId) - .toLowerCase() - .includes('debugger') - ) { - return false; - } - const areRelevantPropertiesEqual = RECORD_PROPERTIES_TO_COMPARE.every( - prop => recordA[prop] === recordB[prop], - ); - - // if data exists, we should not accumulate this into the previous record - const doesDataExist = recordA.data || recordB.data; - - const recATags = recordA.tags; - const recBTags = recordB.tags; - const areTagsEqual = - (!recATags && !recBTags) || - (recATags && recBTags && arrayEqual(recATags, recBTags)); - - return ( - areRelevantPropertiesEqual && - !Boolean(doesDataExist) && - Boolean(areTagsEqual) - ); -} - -export default function accumulateState( - state: AppState, - action: Action, -): AppState { - switch (action.type) { - case Actions.RECORD_RECEIVED: { - const {record} = action.payload; - let nextRecords = state.records; - - // check if the message is exactly the same as the previous one, if so - // we add a count to it. - const lastRecord = nextRecords.last(); - if ( - lastRecord != null && - shouldAccumulateRecordCount(lastRecord, record) - ) { - // Update the last record. Don't use `splice()` because that's O(n) - const updatedRecord: Record = { - ...lastRecord, - repeatCount: lastRecord.repeatCount + 1, - timestamp: record.timestamp, - }; - nextRecords = nextRecords.pop().push(updatedRecord); - } else { - nextRecords = nextRecords.push(record); +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +accumulateState;var _immutable;function _load_immutable() {return _immutable = require('immutable');}var _collection;function _load_collection() {return _collection = require('nuclide-commons/collection');}var _Actions;function _load_Actions() {return _Actions = _interopRequireWildcard(require('./Actions'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} /** + * 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. + * + * + * @format + */const RECORD_PROPERTIES_TO_COMPARE = ['text', 'level', 'format', 'scopeName', 'sourceId', 'kind'];function shouldAccumulateRecordCount(recordA, recordB) {if (String(recordA.sourceId).toLowerCase().includes('debugger') || String(recordB.sourceId).toLowerCase().includes('debugger')) {return false;}const areRelevantPropertiesEqual = RECORD_PROPERTIES_TO_COMPARE.every(prop => recordA[prop] === recordB[prop]); // if data exists, we should not accumulate this into the previous record + const doesDataExist = recordA.data || recordB.data;const recATags = recordA.tags;const recBTags = recordB.tags;const areTagsEqual = !recATags && !recBTags || recATags && recBTags && (0, (_collection || _load_collection()).arrayEqual)(recATags, recBTags);return areRelevantPropertiesEqual && !Boolean(doesDataExist) && Boolean(areTagsEqual);}function accumulateState(state, action) {switch (action.type) {case (_Actions || _load_Actions()).RECORD_RECEIVED:{const { record } = action.payload;let nextRecords = state.records; // check if the message is exactly the same as the previous one, if so + // we add a count to it. + const lastRecord = nextRecords.last();if (lastRecord != null && + shouldAccumulateRecordCount(lastRecord, record)) + { + // Update the last record. Don't use `splice()` because that's O(n) + const updatedRecord = Object.assign({}, + lastRecord, { + repeatCount: lastRecord.repeatCount + 1, + timestamp: record.timestamp }); + + nextRecords = nextRecords.pop().push(updatedRecord); + } else { + nextRecords = nextRecords.push(record); + } + + if (nextRecords.size > state.maxMessageCount) { + // We could only have gone over by one. + nextRecords = nextRecords.shift(); + } + + return Object.assign({}, + state, { + records: nextRecords }); + + } + case (_Actions || _load_Actions()).SET_MAX_MESSAGE_COUNT:{ + const { maxMessageCount } = action.payload; + if (maxMessageCount <= 0) { + return state; + } + return Object.assign({}, + state, { + maxMessageCount, + records: state.records.slice(-maxMessageCount) }); + + } + case (_Actions || _load_Actions()).REGISTER_SOURCE:{ + const { source } = action.payload; + return Object.assign({}, + state, { + providers: new Map(state.providers).set(source.id, Object.assign({}, + source, { + name: source.name || source.id })) }); + + } + case (_Actions || _load_Actions()).CLEAR_RECORDS:{ + return Object.assign({}, + state, { + records: (0, (_immutable || _load_immutable()).List)() }); - if (nextRecords.size > state.maxMessageCount) { - // We could only have gone over by one. - nextRecords = nextRecords.shift(); } + case (_Actions || _load_Actions()).REGISTER_EXECUTOR:{ + const { executor } = action.payload; + return Object.assign({}, + state, { + executors: new Map(state.executors).set(executor.id, executor) }); - return { - ...state, - records: nextRecords, - }; - } - case Actions.SET_MAX_MESSAGE_COUNT: { - const {maxMessageCount} = action.payload; - if (maxMessageCount <= 0) { - return state; } - return { - ...state, - maxMessageCount, - records: state.records.slice(-maxMessageCount), - }; - } - case Actions.REGISTER_SOURCE: { - const {source} = action.payload; - return { - ...state, - providers: new Map(state.providers).set(source.id, { - ...source, - name: source.name || source.id, - }), - }; - } - case Actions.CLEAR_RECORDS: { - return { - ...state, - records: List(), - }; - } - case Actions.REGISTER_EXECUTOR: { - const {executor} = action.payload; - return { - ...state, - executors: new Map(state.executors).set(executor.id, executor), - }; - } - case Actions.SELECT_EXECUTOR: { - const {executorId} = action.payload; - return { - ...state, - currentExecutorId: executorId, - }; - } - case Actions.REMOVE_SOURCE: { - const {sourceId} = action.payload; - const providers = new Map(state.providers); - const providerStatuses = new Map(state.providerStatuses); - const executors = new Map(state.executors); - providers.delete(sourceId); - providerStatuses.delete(sourceId); - executors.delete(sourceId); - return { - ...state, - providers, - providerStatuses, - executors, - }; - } - case Actions.UPDATE_STATUS: { - const {status, providerId} = action.payload; - return { - ...state, - providerStatuses: new Map(state.providerStatuses).set( + case (_Actions || _load_Actions()).SELECT_EXECUTOR:{ + const { executorId } = action.payload; + return Object.assign({}, + state, { + currentExecutorId: executorId }); + + } + case (_Actions || _load_Actions()).REMOVE_SOURCE:{ + const { sourceId } = action.payload; + const providers = new Map(state.providers); + const providerStatuses = new Map(state.providerStatuses); + const executors = new Map(state.executors); + providers.delete(sourceId); + providerStatuses.delete(sourceId); + executors.delete(sourceId); + return Object.assign({}, + state, { + providers, + providerStatuses, + executors }); + + } + case (_Actions || _load_Actions()).UPDATE_STATUS:{ + const { status, providerId } = action.payload; + return Object.assign({}, + state, { + providerStatuses: new Map(state.providerStatuses).set( providerId, - status, - ), - }; - } - case Actions.EXECUTE: { - const command = action.payload.code; - return { - ...state, - history: state.history.concat(command).slice(-1000), - }; - } - case Actions.SET_CREATE_PASTE_FUNCTION: { - const {createPasteFunction} = action.payload; - return { - ...state, - createPasteFunction, - }; - } - case Actions.SET_WATCH_EDITOR_FUNCTION: { - const {watchEditor} = action.payload; - return { - ...state, - watchEditor, - }; - } - case Actions.SET_FONT_SIZE: { - const {fontSize} = action.payload; - return { - ...state, - fontSize, - }; - } - } + status) }); + + + } + case (_Actions || _load_Actions()).EXECUTE:{ + const command = action.payload.code; + return Object.assign({}, + state, { + history: state.history.concat(command).slice(-1000) }); + + } + case (_Actions || _load_Actions()).SET_CREATE_PASTE_FUNCTION:{ + const { createPasteFunction } = action.payload; + return Object.assign({}, + state, { + createPasteFunction }); + + } + case (_Actions || _load_Actions()).SET_WATCH_EDITOR_FUNCTION:{ + const { watchEditor } = action.payload; + return Object.assign({}, + state, { + watchEditor }); + + } + case (_Actions || _load_Actions()).SET_FONT_SIZE:{ + const { fontSize } = action.payload; + return Object.assign({}, + state, { + fontSize }); + + }} + return state; -} +} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/lib/types.js b/modules/atom-ide-ui/pkg/atom-ide-console/lib/types.js index 0b02b291..a726efc4 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/lib/types.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/lib/types.js @@ -1,315 +1 @@ -/** - * 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 - * @format - */ - -import type {Observable} from 'rxjs'; -import type {List} from 'immutable'; -import type {EvaluationResult} from 'nuclide-commons-ui/TextRenderer'; -import type {ExpansionResult} from 'nuclide-commons-ui/LazyNestedValueComponent'; - -// The type of the object passed to your package's `consumeConsole()` function. -export type ConsoleService = (options: SourceInfo) => ConsoleApi; - -// The console API. An object of this type is returned when you invoke the function provided by the -// console service. -export type ConsoleApi = { - // The primary means of interacting with the console. - // TODO: Update these to be `(object: any, ...objects: Array): void` to allow for logging objects. - log(object: string, _: void): void, - error(object: string, _: void): void, - warn(object: string, _: void): void, - info(object: string, _: void): void, - success(object: string, _: void): void, - - // A generic API for sending a message of any level (log, error, etc.). - append(message: Message): void, - - // Dispose of the console. Invoke this when your package is disabled. - dispose(): void, - - // Set the status of the source. See "Stoppable Sources" below. - setStatus(status: OutputProviderStatus): void, -}; - -// A type representing the possible values for the `console.setStatus()` API. -export type OutputProviderStatus = 'starting' | 'running' | 'stopped'; - -// The shape of the argument to the `ConsoleService` function. -export type SourceInfo = { - id: string, // A unique identifier representing this source. - name: string, // A human-readable name for the source. This will be used in the UI. - - // `start()` and `stop()` functions can optionally be provided. See [User-Controllable Console - // Sources](https://github.com/facebook-atom/atom-ide-ui/blob/master/docs/console.md#user-controllable-console-sources) - // for more information. - start?: () => void, - stop?: () => void, -}; - -// Message levels. For use with the `console.append()` API. -export type Level = - | 'info' - | 'log' - | 'warning' - | 'error' - | 'debug' - | 'success' - | Color; -type Color = - | 'red' - | 'orange' - | 'yellow' - | 'green' - | 'blue' - | 'purple' - | 'violet' - | 'rainbow'; - -// A message object, for use with the `console.append()` API. -export type Message = { - text: string, - level: Level, - format?: MessageFormat, - - // Internally used properties. These are subject to change so don't use em! - data?: EvaluationResult, - tags?: ?Array, - kind?: ?MessageKind, - scopeName?: ?string, -}; - -// -// -// The following types are part of deprecated APIs and shouldn't be used outside of this package. -// -// - -type BasicOutputProvider = { - messages: Observable, - // The source can't be part of the message because we want to be able to populate a filter menu - // before we even have any messages. - id: string, - getProperties?: (objectId: string) => Observable, -}; - -type ControllableOutputProviderProps = { - observeStatus(callback: (status: OutputProviderStatus) => mixed): IDisposable, - start(): void, - stop(): void, -}; - -type ControllableOutputProvider = BasicOutputProvider & - ControllableOutputProviderProps; - -export type OutputProvider = BasicOutputProvider | ControllableOutputProvider; - -export type OutputService = { - registerOutputProvider(outputProvider: OutputProvider): IDisposable, -}; - -// -// -// The following types aren't part of public API but rather are used within the package. -// -// - -type MessageKind = 'message' | 'request' | 'response'; -type MessageFormat = 'ansi'; - -// A normalized type used internally to represent all possible kinds of messages. Responses and -// Messages are transformed into these. -// Make sure shouldAccumulateRecordCount in Reducers.js is up to date with these fields -export type Record = { - text: string, - level: Level, - format?: MessageFormat, - tags?: ?Array, - repeatCount: number, - - kind: MessageKind, - sourceId: string, - scopeName: ?string, - data?: ?EvaluationResult, - timestamp: Date, - - executor?: Executor, -}; - -export type AppState = { - createPasteFunction: ?CreatePasteFunction, - currentExecutorId: ?string, - executors: Map, - maxMessageCount: number, - // We use Immutable for the records list so that adding an item is O(1). However, rendering the - // items after the addition is O(n), so it's important that we schedule and throttle our renders - // or we'll lose the benefit of an O(1) insertion. - records: List, - history: Array, - providers: Map, - providerStatuses: Map, -}; - -// A special type used internally by the Console component to represent each record that is -// displayed with its height. This is stored at the component level since the expansion state of any -// record (which affects its height) is unique to each Console pane (whereas the records themselves -// are shared between all Console panes). The height is needed for partial rendering. -export type DisplayableRecord = { - id: number, - record: Record, - height: number, - expansionStateId: Object, -}; - -export type RecordHeightChangeHandler = ( - recordId: number, - newHeight: number, - callback: () => void, -) => void; - -export type Source = { - id: string, - name: string, - status: OutputProviderStatus, - start?: () => void, - stop?: () => void, -}; - -type BasicRecordProvider = { - records: Observable, - id: string, - getProperties?: (objectId: string) => Observable, -}; - -type ControllableRecordProvider = BasicRecordProvider & - ControllableOutputProviderProps; - -export type RecordProvider = BasicRecordProvider | ControllableRecordProvider; - -// Serialized state specific to each instance of the console view. For example, each instance has -// its own, distinct filter, so that's here. They don't, however, have distinct records, so they -// aren't. -export type ConsolePersistedState = { - deserializer: 'nuclide.Console', - filterText?: string, - enableRegExpFilter?: boolean, - unselectedSourceIds?: Array, -}; - -export type Executor = { - id: string, - name: string, - send(message: string): void, - output: Observable, - scopeName: string, - provideSymbols?: (prefix: string) => Array, - getProperties?: (objectId: string) => Observable, -}; - -export type RegisterExecutorFunction = (executor: Executor) => IDisposable; - -export type WatchEditorFunction = ( - editor: atom$TextEditor, - labels?: Array, -) => IDisposable; - -export type PasteOptions = { - language?: ?string, - title?: ?string, -}; - -export type CreatePasteFunction = ( - message: string, - options: PasteOptions, - source: string, -) => Promise; - -export type Store = { - getState(): AppState, - dispatch(action: Action): void, -}; - -export type Action = - | { - type: 'CLEAR_RECORDS', - } - | { - type: 'REGISTER_EXECUTOR', - payload: { - executor: Executor, - }, - } - | { - type: 'EXECUTE', - payload: { - code: string, - }, - } - | { - type: 'RECORD_RECEIVED', - payload: { - record: Record, - }, - } - | { - type: 'REGISTER_RECORD_PROVIDER', - payload: { - recordProvider: RecordProvider, - }, - } - | { - type: 'REGISTER_SOURCE', - payload: { - source: SourceInfo, - }, - } - | { - type: 'REMOVE_SOURCE', - payload: { - sourceId: string, - }, - } - | { - type: 'SELECT_EXECUTOR', - payload: { - executorId: string, - }, - } - | { - type: 'SET_CREATE_PASTE_FUNCTION', - payload: { - createPasteFunction: ?CreatePasteFunction, - }, - } - | { - type: 'SET_WATCH_EDITOR_FUNCTION', - payload: { - watchEditor: ?WatchEditorFunction, - }, - } - | { - type: 'SET_MAX_MESSAGE_COUNT', - payload: { - maxMessageCount: number, - }, - } - | { - type: 'UPDATE_STATUS', - payload: { - providerId: string, - status: OutputProviderStatus, - }, - } - | { - type: 'SET_FONT_SIZE', - payload: { - fontSize: number, - }, - }; +'use strict'; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/Console.js b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/Console.js index badf2472..2f3c9ef3 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/Console.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/Console.js @@ -1,605 +1,648 @@ -/** - * 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 - * @format - */ - -/* eslint-env browser */ - -import type { - ConsolePersistedState, - DisplayableRecord, - OutputProviderStatus, - Record, - Source, - Store, - SourceInfo, -} from '../types'; -import type {CreatePasteFunction} from '../types'; -import type {RegExpFilterChange} from 'nuclide-commons-ui/RegExpFilter'; -import type {Executor} from '../types'; - -import observePaneItemVisibility from 'nuclide-commons-atom/observePaneItemVisibility'; -import Model from 'nuclide-commons/Model'; -import shallowEqual from 'shallowequal'; -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import {renderReactRoot} from 'nuclide-commons-ui/renderReactRoot'; -import memoizeUntilChanged from 'nuclide-commons/memoizeUntilChanged'; -import {toggle} from 'nuclide-commons/observable'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {nextAnimationFrame} from 'nuclide-commons/observable'; -import {getFilterPattern} from 'nuclide-commons-ui/RegExpFilter'; -import getCurrentExecutorId from '../getCurrentExecutorId'; -import * as Actions from '../redux/Actions'; -import ConsoleView from './ConsoleView'; -import {List} from 'immutable'; -import * as React from 'react'; -import {Observable, ReplaySubject} from 'rxjs'; - -type Options = { - store: Store, - initialFilterText?: string, - initialEnableRegExpFilter?: boolean, - initialUnselectedSourceIds?: Array, -}; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.Console = exports.WORKSPACE_VIEW_URI = undefined;var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));let serializeRecordObject = (() => {var _ref2 = (0, _asyncToGenerator.default)( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -// -// State unique to this particular Console instance -// -type State = { - displayableRecords: Array, - filterText: string, - enableRegExpFilter: boolean, - unselectedSourceIds: Array, -}; - -type BoundActionCreators = { - execute: (code: string) => void, - selectExecutor: (executorId: string) => void, - clearRecords: () => void, -}; - -// Other Nuclide packages (which cannot import this) depend on this URI. If this -// needs to be changed, grep for CONSOLE_VIEW_URI and ensure that the URIs match. -export const WORKSPACE_VIEW_URI = 'atom://nuclide/console'; -const ERROR_TRANSCRIBING_MESSAGE = - "// Nuclide couldn't find the right text to display"; -const INITIAL_RECORD_HEIGHT = 21; -/** - * An Atom "view model" for the console. This object is responsible for creating a stateful view - * (via `getElement()`). That view is bound to both global state (from the store) and view-specific - * state (from this instance's `_model`). - */ -export class Console { - _actionCreators: BoundActionCreators; - - // Associates Records with their display state (height, expansionStateId). - _displayableRecords: WeakMap; - - _nextRecordId: number; - _titleChanges: Observable; - _model: Model; - _store: Store; - _element: ?HTMLElement; - _destroyed: ReplaySubject; - - constructor(options: Options) { - const { - store, - initialFilterText, - initialEnableRegExpFilter, - initialUnselectedSourceIds, - } = options; - this._model = new Model({ - displayableRecords: [], - filterText: initialFilterText == null ? '' : initialFilterText, - enableRegExpFilter: Boolean(initialEnableRegExpFilter), - unselectedSourceIds: - initialUnselectedSourceIds == null ? [] : initialUnselectedSourceIds, - }); - this._store = store; - this._nextRecordId = 0; - this._displayableRecords = new WeakMap(); - this._destroyed = new ReplaySubject(1); - - this._titleChanges = Observable.combineLatest( - this._model.toObservable(), - // $FlowIssue: Flow doesn't know about Symbol.observable - Observable.from(store), - ) - .takeUntil(this._destroyed) - .map(() => this.getTitle()) - .distinctUntilChanged() - .share(); - } - - getIconName(): string { - return 'terminal'; - } - - // Get the pane item's title. If there's only one source selected, we'll use that to make a more - // descriptive title. - getTitle(): string { - const enabledProviderCount = this._store.getState().providers.size; - const {unselectedSourceIds} = this._model.state; - // Calling `_getSources()` is (currently) expensive because it needs to search all the records - // for sources that have been disabled but still have records. We try to avoid calling it if we - // already know that there's more than one selected source. - if (enabledProviderCount - unselectedSourceIds.length > 1) { - return 'Console'; - } - // If there's only one source selected, use its name in the tab title. - const sources = this._getSources(); - if (sources.length - unselectedSourceIds.length === 1) { - const selectedSource = sources.find( - source => unselectedSourceIds.indexOf(source.id) === -1, - ); - if (selectedSource) { - return `Console: ${selectedSource.name}`; - } - } - return 'Console'; - } - getDefaultLocation(): string { - return 'bottom'; - } - getURI(): string { - return WORKSPACE_VIEW_URI; - } - onDidChangeTitle(callback: (title: string) => mixed): IDisposable { - return new UniversalDisposable(this._titleChanges.subscribe(callback)); - } - _getSources(): Array { - const {providers, providerStatuses, records} = this._store.getState(); - return this._getSourcesMemoized({providers, providerStatuses, records}); - } - // Memoize `getSources()`. Unfortunately, since we look for unrepresented sources in the record - // list, this still needs to be called whenever the records change. - // TODO: Consider removing records when their source is removed. This will likely require adding - // the ability to enable and disable sources so, for example, when the debugger is no longer - // active, it still remains in the source list. - _getSourcesMemoized = memoizeUntilChanged( - getSources, - opts => opts, - (a, b) => shallowEqual(a, b), - ); - - destroy(): void { - this._destroyed.next(); - } - - copy(): Console { - return new Console({ - store: this._store, - initialFilterText: this._model.state.filterText, - initialEnableRegExpFilter: this._model.state.enableRegExpFilter, - initialUnselectedSourceIds: this._model.state.unselectedSourceIds, - }); - } - - _getBoundActionCreators(): BoundActionCreators { - if (this._actionCreators == null) { - this._actionCreators = { - execute: code => { - this._store.dispatch(Actions.execute(code)); - }, - selectExecutor: executorId => { - this._store.dispatch(Actions.selectExecutor(executorId)); - }, - clearRecords: () => { - this._store.dispatch(Actions.clearRecords()); - }, - }; - } - return this._actionCreators; - } - - _resetAllFilters = (): void => { - this._selectSources(this._getSources().map(s => s.id)); - this._model.setState({filterText: ''}); - }; - - _createPaste = async (): Promise => { - const displayableRecords = this._getDisplayableRecords(); - const createPasteImpl = this._store.getState().createPasteFunction; - if (createPasteImpl == null) { - return; - } - return createPaste(createPasteImpl, displayableRecords); - }; - - _getFilterInfo(): { - invalid: boolean, - selectedSourceIds: Array, - filteredRecords: Array, - } { - const {pattern, invalid} = getFilterPattern( - this._model.state.filterText, - this._model.state.enableRegExpFilter, - ); - const sources = this._getSources(); - const selectedSourceIds = sources - .map(source => source.id) - .filter( - sourceId => - this._model.state.unselectedSourceIds.indexOf(sourceId) === -1, - ); - - const filteredRecords = filterRecords( - this._getDisplayableRecords(), - selectedSourceIds, - pattern, - sources.length !== selectedSourceIds.length, - ); - - return { - invalid, - selectedSourceIds, - filteredRecords, - }; - } - getElement(): HTMLElement { - if (this._element != null) { - return this._element; - } - const actionCreators = this._getBoundActionCreators(); - const props = Observable.combineLatest( - this._model.toObservable(), - // $FlowIssue: Flow doesn't know about Symbol.observable - Observable.from(this._store), - ) - // Don't re-render when the console isn't visible. - .let(toggle(observePaneItemVisibility(this))) - .audit(() => nextAnimationFrame) - .map(([localState, globalState]) => { - const { - invalid, - selectedSourceIds, - filteredRecords, - } = this._getFilterInfo(); - - const currentExecutorId = getCurrentExecutorId(globalState); - const currentExecutor = - currentExecutorId != null - ? globalState.executors.get(currentExecutorId) - : null; - - return { - invalidFilterInput: invalid, - execute: actionCreators.execute, - selectExecutor: actionCreators.selectExecutor, - clearRecords: actionCreators.clearRecords, - createPaste: - globalState.createPasteFunction == null ? null : this._createPaste, - watchEditor: globalState.watchEditor, - currentExecutor, - unselectedSourceIds: localState.unselectedSourceIds, - filterText: localState.filterText, - enableRegExpFilter: localState.enableRegExpFilter, - displayableRecords: filteredRecords, - filteredRecordCount: - globalState.records.size - filteredRecords.length, - history: globalState.history, - sources: this._getSources(), - selectedSourceIds, - selectSources: this._selectSources, - executors: globalState.executors, - getProvider: id => globalState.providers.get(id), - updateFilter: this._updateFilter, - onDisplayableRecordHeightChange: this - ._handleDisplayableRecordHeightChange, - resetAllFilters: this._resetAllFilters, - fontSize: globalState.fontSize, - }; - }); - - const StatefulConsoleView = bindObservableAsProps(props, ConsoleView); - return (this._element = renderReactRoot()); - } - - serialize(): ConsolePersistedState { - const { - filterText, - enableRegExpFilter, - unselectedSourceIds, - } = this._model.state; - return { - deserializer: 'nuclide.Console', - filterText, - enableRegExpFilter, - unselectedSourceIds, - }; - } - - _selectSources = (selectedSourceIds: Array): void => { - const sourceIds = this._getSources().map(source => source.id); - const unselectedSourceIds = sourceIds.filter( - sourceId => selectedSourceIds.indexOf(sourceId) === -1, - ); - this._model.setState({unselectedSourceIds}); - }; - - _updateFilter = (change: RegExpFilterChange): void => { - const {text, isRegExp} = change; - this._model.setState({ - filterText: text, - enableRegExpFilter: isRegExp, - }); - }; - - _handleDisplayableRecordHeightChange = ( - recordId: number, - newHeight: number, - callback: () => void, - ): void => { - const {records} = this._store.getState(); - const nextDisplayableRecords = Array(records.size); - records.forEach((record, i) => { - let displayableRecord = this._toDisplayableRecord(record); - if (displayableRecord.id === recordId) { - // Update the record with the new height. - displayableRecord = { - ...displayableRecord, - height: newHeight, - }; - this._displayableRecords.set(record, displayableRecord); - } - nextDisplayableRecords[i] = displayableRecord; - }); - this._model.setState({displayableRecords: nextDisplayableRecords}); - requestAnimationFrame(callback); - }; - _getDisplayableRecords(): Array { - const {records} = this._store.getState(); - const displayableRecords = Array(records.size); - records.forEach((record, i) => { - displayableRecords[i] = this._toDisplayableRecord(record); - }); - return displayableRecords; - } - - /** - * Transforms the Records from the store into DisplayableRecords. This caches the result - * per-Console instance because the same record can have different heights in different - * containers. - */ - _toDisplayableRecord(record: Record): DisplayableRecord { - const displayableRecord = this._displayableRecords.get(record); - if (displayableRecord != null) { - return displayableRecord; - } - const newDisplayableRecord = { - id: this._nextRecordId++, - record, - height: INITIAL_RECORD_HEIGHT, - expansionStateId: {}, + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + function* ( + executor, + visited, + data, + + + + + text, + level) + { + const getText = function (record) { + let indent = ''; + for (let i = 0; i < level; i++) { + indent += '\t'; + } + return ( + indent + ( + record.description != null ? + record.description : + record.value != null ? + record.value : + '')); + }; - this._displayableRecords.set(record, newDisplayableRecord); - return newDisplayableRecord; - } -} - -function getSources(options: { - records: List, - providers: Map, - providerStatuses: Map, -}): Array { - const {providers, providerStatuses, records} = options; - - // Convert the providers to a map of sources. - const mapOfSources = new Map( - Array.from(providers.entries()).map(([k, provider]) => { - const source = { - id: provider.id, - name: provider.id, - status: providerStatuses.get(provider.id) || 'stopped', - start: - typeof provider.start === 'function' ? provider.start : undefined, - stop: typeof provider.stop === 'function' ? provider.stop : undefined, - }; - return [k, source]; - }), - ); - - // Some providers may have been unregistered, but still have records. Add sources for them too. - // TODO: Iterating over all the records to get this every time we get a new record is inefficient. - records.forEach((record, i) => { - if (!mapOfSources.has(record.sourceId)) { - mapOfSources.set(record.sourceId, { - id: record.sourceId, - name: record.sourceId, - status: 'stopped', - start: undefined, - stop: undefined, - }); + + if (data.objectId == null) { + // Leaf node. + return text + getText(data); } - }); - - return Array.from(mapOfSources.values()); -} - -function filterRecords( - displayableRecords: Array, - selectedSourceIds: Array, - filterPattern: ?RegExp, - filterSources: boolean, -): Array { - if (!filterSources && filterPattern == null) { - return displayableRecords; - } - - return displayableRecords.filter(({record}) => { - // Only filter regular messages - if (record.kind !== 'message') { - return true; + + const id = data.objectId; + if (visited.has(id)) { + // Guard against cycles. + return text; } - const sourceMatches = selectedSourceIds.indexOf(record.sourceId) !== -1; - return ( - sourceMatches && - (filterPattern == null || filterPattern.test(record.text)) - ); - }); -} - -async function serializeRecordObject( - executor: Executor, - visited: Set, - data: { - objectId?: string, - description?: string, - value?: string, - }, - text: string, - level: number, -): Promise { - const getText = record => { - let indent = ''; - for (let i = 0; i < level; i++) { - indent += '\t'; + visited.add(id); + + if (executor.getProperties == null) { + return text; } - return ( - indent + - (record.description != null - ? record.description - : record.value != null - ? record.value - : '') - ); - }; - - if (data.objectId == null) { - // Leaf node. - return text + getText(data); - } - - const id = data.objectId; - if (visited.has(id)) { - // Guard against cycles. - return text; - } - - visited.add(id); - - if (executor.getProperties == null) { - return text; - } - - const childProperties = (await executor.getProperties(id).toPromise()) || []; - const serializedProps = childProperties.map(childProp => { - return serializeRecordObject( + + const childProperties = (yield executor.getProperties(id).toPromise()) || []; + const serializedProps = childProperties.map(function (childProp) { + return serializeRecordObject( executor, visited, childProp.value, '', - level + 1, - ); - }); - return getText(data) + '\n' + (await Promise.all(serializedProps)).join('\n'); -} - -async function createPaste( - createPasteImpl: CreatePasteFunction, - records: Array, -): Promise { - const linePromises = records - .filter( - displayable => + level + 1); + + }); + return getText(data) + '\n' + (yield Promise.all(serializedProps)).join('\n'); + });return function serializeRecordObject(_x, _x2, _x3, _x4, _x5) {return _ref2.apply(this, arguments);};})();let createPaste = (() => {var _ref3 = (0, _asyncToGenerator.default)( + + function* ( + createPasteImpl, + records) + { + const linePromises = records. + filter( + function (displayable) {return ( displayable.record.kind === 'message' || displayable.record.kind === 'request' || - displayable.record.kind === 'response', - ) - .map(async displayable => { - const record = displayable.record; - const level = + displayable.record.kind === 'response');}). + + map((() => {var _ref4 = (0, _asyncToGenerator.default)(function* (displayable) { + const record = displayable.record; + const level = record.level != null ? record.level.toString().toUpperCase() : 'LOG'; - const timestamp = record.timestamp.toLocaleString(); - let text = + const timestamp = record.timestamp.toLocaleString(); + let text = record.text || - (record.data && record.data.value) || + record.data && record.data.value || ERROR_TRANSCRIBING_MESSAGE; - if ( + if ( record.kind === 'response' && record.data != null && record.data.objectId != null && - record.data.objectId !== '' - ) { - const executor = record.executor; - if (executor != null) { - // If the record has a data object, and the object has an ID, - // recursively expand the nodes of the object and serialize it - // for the paste. - text = await serializeRecordObject( + record.data.objectId !== '') + { + const executor = record.executor; + if (executor != null) { + // If the record has a data object, and the object has an ID, + // recursively expand the nodes of the object and serialize it + // for the paste. + text = yield serializeRecordObject( executor, new Set(), record.data, '', - 0, - ); + 0); + + } } - } - return `[${level}][${record.sourceId}][${timestamp}]\t ${text}`; - }); + return `[${level}][${record.sourceId}][${timestamp}]\t ${text}`; + });return function (_x8) {return _ref4.apply(this, arguments);};})()); + + const lines = (yield Promise.all(linePromises)).join('\n'); - const lines = (await Promise.all(linePromises)).join('\n'); + if (lines === '') { + // Can't create an empty paste! + atom.notifications.addWarning( + 'There is nothing in your console to Paste! Check your console filters and try again.'); - if (lines === '') { - // Can't create an empty paste! - atom.notifications.addWarning( - 'There is nothing in your console to Paste! Check your console filters and try again.', - ); - return; - } + return; + } - atom.notifications.addInfo('Creating Paste...'); + atom.notifications.addInfo('Creating Paste...'); - try { - const uri = await createPasteImpl( + try { + const uri = yield createPasteImpl( lines, { - title: 'Nuclide Console Paste', - }, - 'console paste', - ); - atom.notifications.addSuccess(`Created Paste at ${uri}`); - } catch (error) { - if (error.stdout == null) { - atom.notifications.addError( - `Failed to create paste: ${String(error.message || error)}`, - ); - return; + title: 'Nuclide Console Paste' }, + + 'console paste'); + + atom.notifications.addSuccess(`Created Paste at ${uri}`); + } catch (error) { + if (error.stdout == null) { + atom.notifications.addError( + `Failed to create paste: ${String(error.message || error)}`); + + return; + } + const errorMessages = error.stdout. + trim(). + split('\n'). + map(JSON.parse). + map(function (e) {return e.message;}); + atom.notifications.addError('Failed to create paste', { + detail: errorMessages.join('\n'), + dismissable: true }); + } - const errorMessages = error.stdout - .trim() - .split('\n') - .map(JSON.parse) - .map(e => e.message); - atom.notifications.addError('Failed to create paste', { - detail: errorMessages.join('\n'), - dismissable: true, - }); - } -} + });return function createPaste(_x6, _x7) {return _ref3.apply(this, arguments);};})();var _observePaneItemVisibility;function _load_observePaneItemVisibility() {return _observePaneItemVisibility = _interopRequireDefault(require('nuclide-commons-atom/observePaneItemVisibility'));}var _Model;function _load_Model() {return _Model = _interopRequireDefault(require('nuclide-commons/Model'));}var _shallowequal;function _load_shallowequal() {return _shallowequal = _interopRequireDefault(require('shallowequal'));}var _bindObservableAsProps;function _load_bindObservableAsProps() {return _bindObservableAsProps = require('nuclide-commons-ui/bindObservableAsProps');}var _renderReactRoot;function _load_renderReactRoot() {return _renderReactRoot = require('nuclide-commons-ui/renderReactRoot');}var _memoizeUntilChanged;function _load_memoizeUntilChanged() {return _memoizeUntilChanged = _interopRequireDefault(require('nuclide-commons/memoizeUntilChanged'));}var _observable;function _load_observable() {return _observable = require('nuclide-commons/observable');}var _UniversalDisposable;function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _RegExpFilter;function _load_RegExpFilter() {return _RegExpFilter = require('nuclide-commons-ui/RegExpFilter');}var _getCurrentExecutorId;function _load_getCurrentExecutorId() {return _getCurrentExecutorId = _interopRequireDefault(require('../getCurrentExecutorId'));}var _Actions;function _load_Actions() {return _Actions = _interopRequireWildcard(require('../redux/Actions'));}var _ConsoleView;function _load_ConsoleView() {return _ConsoleView = _interopRequireDefault(require('./ConsoleView'));}var _immutable;function _load_immutable() {return _immutable = require('immutable');}var _react = _interopRequireWildcard(require('react'));var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} // Other Nuclide packages (which cannot import this) depend on this URI. If this +// needs to be changed, grep for CONSOLE_VIEW_URI and ensure that the URIs match. +// +// State unique to this particular Console instance +// +/** + * 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. + * + * + * @format + */ /* eslint-env browser */const WORKSPACE_VIEW_URI = exports.WORKSPACE_VIEW_URI = 'atom://nuclide/console';const ERROR_TRANSCRIBING_MESSAGE = "// Nuclide couldn't find the right text to display";const INITIAL_RECORD_HEIGHT = 21; /** + * An Atom "view model" for the console. This object is responsible for creating a stateful view + * (via `getElement()`). That view is bound to both global state (from the store) and view-specific + * state (from this instance's `_model`). + */class Console {constructor(options) {var _this = this;this._getSourcesMemoized = (0, (_memoizeUntilChanged || _load_memoizeUntilChanged()).default)(getSources, opts => opts, (a, b) => (0, (_shallowequal || _load_shallowequal()).default)(a, b));this._resetAllFilters = () => {this._selectSources(this._getSources().map(s => s.id));this._model.setState({ filterText: '' });};this._createPaste = (0, _asyncToGenerator.default)(function* () {const displayableRecords = _this._getDisplayableRecords();const createPasteImpl = _this._store.getState().createPasteFunction;if (createPasteImpl == null) {return;}return createPaste(createPasteImpl, displayableRecords);});this._selectSources = selectedSourceIds => {const sourceIds = this._getSources().map(source => source.id);const unselectedSourceIds = sourceIds.filter(sourceId => selectedSourceIds.indexOf(sourceId) === -1);this._model.setState({ unselectedSourceIds });};this._updateFilter = change => {const { text, isRegExp } = change;this._model.setState({ filterText: text, enableRegExpFilter: isRegExp });};this._handleDisplayableRecordHeightChange = (recordId, newHeight, callback) => {const { records } = this._store.getState();const nextDisplayableRecords = Array(records.size);records.forEach((record, i) => {let displayableRecord = this._toDisplayableRecord(record);if (displayableRecord.id === recordId) {// Update the record with the new height. + displayableRecord = Object.assign({}, displayableRecord, { height: newHeight });this._displayableRecords.set(record, displayableRecord);}nextDisplayableRecords[i] = displayableRecord;});this._model.setState({ displayableRecords: nextDisplayableRecords });requestAnimationFrame(callback);};const { store, initialFilterText, initialEnableRegExpFilter, initialUnselectedSourceIds } = options;this._model = new (_Model || _load_Model()).default({ displayableRecords: [], filterText: initialFilterText == null ? '' : initialFilterText, enableRegExpFilter: Boolean(initialEnableRegExpFilter), unselectedSourceIds: initialUnselectedSourceIds == null ? [] : initialUnselectedSourceIds });this._store = store;this._nextRecordId = 0;this._displayableRecords = new WeakMap();this._destroyed = new _rxjsBundlesRxMinJs.ReplaySubject(1);this._titleChanges = _rxjsBundlesRxMinJs.Observable.combineLatest(this._model.toObservable(), // $FlowIssue: Flow doesn't know about Symbol.observable + _rxjsBundlesRxMinJs.Observable.from(store)).takeUntil(this._destroyed).map(() => this.getTitle()).distinctUntilChanged().share();} // Associates Records with their display state (height, expansionStateId). + getIconName() {return 'terminal';} // Get the pane item's title. If there's only one source selected, we'll use that to make a more + // descriptive title. + getTitle() {const enabledProviderCount = this._store.getState().providers.size;const { unselectedSourceIds } = this._model.state; // Calling `_getSources()` is (currently) expensive because it needs to search all the records + // for sources that have been disabled but still have records. We try to avoid calling it if we + // already know that there's more than one selected source. + if (enabledProviderCount - unselectedSourceIds.length > 1) {return 'Console';} // If there's only one source selected, use its name in the tab title. + const sources = this._getSources();if (sources.length - unselectedSourceIds.length === 1) {const selectedSource = sources.find(source => unselectedSourceIds.indexOf(source.id) === -1);if (selectedSource) {return `Console: ${selectedSource.name}`;}}return 'Console';}getDefaultLocation() {return 'bottom';}getURI() {return WORKSPACE_VIEW_URI;}onDidChangeTitle(callback) {return new (_UniversalDisposable || _load_UniversalDisposable()).default(this._titleChanges.subscribe(callback));}_getSources() {const { providers, providerStatuses, records } = this._store.getState();return this._getSourcesMemoized({ providers, providerStatuses, records });} // Memoize `getSources()`. Unfortunately, since we look for unrepresented sources in the record + // list, this still needs to be called whenever the records change. + // TODO: Consider removing records when their source is removed. This will likely require adding + // the ability to enable and disable sources so, for example, when the debugger is no longer + // active, it still remains in the source list. + destroy() {this._destroyed.next();}copy() {return new Console({ store: this._store, initialFilterText: this._model.state.filterText, initialEnableRegExpFilter: this._model.state.enableRegExpFilter, initialUnselectedSourceIds: this._model.state.unselectedSourceIds });}_getBoundActionCreators() {if (this._actionCreators == null) {this._actionCreators = { execute: code => {this._store.dispatch((_Actions || _load_Actions()).execute(code));}, selectExecutor: executorId => {this._store.dispatch((_Actions || _load_Actions()).selectExecutor(executorId));}, clearRecords: () => {this._store.dispatch((_Actions || _load_Actions()).clearRecords());} };}return this._actionCreators;}_getFilterInfo() {const { pattern, invalid } = (0, (_RegExpFilter || _load_RegExpFilter()).getFilterPattern)(this._model.state.filterText, this._model.state.enableRegExpFilter);const sources = this._getSources();const selectedSourceIds = sources.map(source => source.id).filter(sourceId => this._model.state.unselectedSourceIds.indexOf(sourceId) === -1);const filteredRecords = filterRecords(this._getDisplayableRecords(), selectedSourceIds, pattern, sources.length !== selectedSourceIds.length);return { invalid, selectedSourceIds, filteredRecords };}getElement() {if (this._element != null) {return this._element;}const actionCreators = this._getBoundActionCreators();const props = _rxjsBundlesRxMinJs.Observable.combineLatest(this._model.toObservable(), // $FlowIssue: Flow doesn't know about Symbol.observable + _rxjsBundlesRxMinJs.Observable.from(this._store)) // Don't re-render when the console isn't visible. + .let((0, (_observable || _load_observable()).toggle)((0, (_observePaneItemVisibility || _load_observePaneItemVisibility()).default)(this))).audit(() => (_observable || _load_observable()).nextAnimationFrame).map(([localState, globalState]) => {const { invalid, selectedSourceIds, filteredRecords } = this._getFilterInfo();const currentExecutorId = (0, (_getCurrentExecutorId || _load_getCurrentExecutorId()).default)(globalState);const currentExecutor = currentExecutorId != null ? globalState.executors.get(currentExecutorId) : null;return { invalidFilterInput: invalid, execute: actionCreators.execute, selectExecutor: actionCreators.selectExecutor, clearRecords: actionCreators.clearRecords, createPaste: globalState.createPasteFunction == null ? null : this._createPaste, watchEditor: globalState.watchEditor, currentExecutor, unselectedSourceIds: localState.unselectedSourceIds, filterText: localState.filterText, enableRegExpFilter: localState.enableRegExpFilter, displayableRecords: filteredRecords, filteredRecordCount: globalState.records.size - filteredRecords.length, history: globalState.history, sources: this._getSources(), selectedSourceIds, selectSources: this._selectSources, executors: globalState.executors, getProvider: id => globalState.providers.get(id), updateFilter: this._updateFilter, onDisplayableRecordHeightChange: this._handleDisplayableRecordHeightChange, resetAllFilters: this._resetAllFilters, fontSize: globalState.fontSize };});const StatefulConsoleView = (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)(props, (_ConsoleView || _load_ConsoleView()).default);return this._element = (0, (_renderReactRoot || _load_renderReactRoot()).renderReactRoot)(_react.createElement(StatefulConsoleView, null));}serialize() {const { filterText, enableRegExpFilter, unselectedSourceIds } = this._model.state;return { deserializer: 'nuclide.Console', filterText, enableRegExpFilter, unselectedSourceIds };}_getDisplayableRecords() {const { records } = this._store.getState();const displayableRecords = Array(records.size);records.forEach((record, i) => {displayableRecords[i] = this._toDisplayableRecord(record);});return displayableRecords;} /** + * Transforms the Records from the store into DisplayableRecords. This caches the result + * per-Console instance because the same record can have different heights in different + * containers. + */_toDisplayableRecord(record) {const displayableRecord = this._displayableRecords.get(record);if (displayableRecord != null) {return displayableRecord;}const newDisplayableRecord = { id: this._nextRecordId++, record, height: INITIAL_RECORD_HEIGHT, expansionStateId: {} };this._displayableRecords.set(record, newDisplayableRecord);return newDisplayableRecord;}}exports.Console = Console;function getSources(options) {const { providers, providerStatuses, records } = options; // Convert the providers to a map of sources. + const mapOfSources = new Map(Array.from(providers.entries()).map(([k, provider]) => {const source = { id: provider.id, name: provider.id, status: providerStatuses.get(provider.id) || 'stopped', start: typeof provider.start === 'function' ? provider.start : undefined, stop: typeof provider.stop === 'function' ? provider.stop : undefined };return [k, source];})); // Some providers may have been unregistered, but still have records. Add sources for them too. + // TODO: Iterating over all the records to get this every time we get a new record is inefficient. + records.forEach((record, i) => {if (!mapOfSources.has(record.sourceId)) {mapOfSources.set(record.sourceId, { id: record.sourceId, name: record.sourceId, status: 'stopped', start: undefined, stop: undefined });}});return Array.from(mapOfSources.values());}function filterRecords(displayableRecords, selectedSourceIds, filterPattern, filterSources) {if (!filterSources && filterPattern == null) {return displayableRecords;}return displayableRecords.filter(({ record }) => {// Only filter regular messages + if (record.kind !== 'message') {return true;}const sourceMatches = selectedSourceIds.indexOf(record.sourceId) !== -1;return sourceMatches && (filterPattern == null || filterPattern.test(record.text));});} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/ConsoleHeader.js b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/ConsoleHeader.js index 43061da4..c4d30673 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/ConsoleHeader.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/ConsoleHeader.js @@ -1,198 +1,198 @@ -/** - * 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 - * @format - */ - -import type {Source} from '../types'; -import type {RegExpFilterChange} from 'nuclide-commons-ui/RegExpFilter'; - -import {LoadingSpinner} from 'nuclide-commons-ui/LoadingSpinner'; -import * as React from 'react'; -import {ModalMultiSelect} from 'nuclide-commons-ui/ModalMultiSelect'; -import RegExpFilter from 'nuclide-commons-ui/RegExpFilter'; -import {Toolbar} from 'nuclide-commons-ui/Toolbar'; -import {ToolbarLeft} from 'nuclide-commons-ui/ToolbarLeft'; -import {ToolbarRight} from 'nuclide-commons-ui/ToolbarRight'; -import addTooltip from 'nuclide-commons-ui/addTooltip'; - -import {Button, ButtonSizes} from 'nuclide-commons-ui/Button'; -import invariant from 'assert'; - -type Props = { - clear: () => void, - createPaste: ?() => Promise, - invalidFilterInput: boolean, - enableRegExpFilter: boolean, - onFilterChange: (change: RegExpFilterChange) => void, - selectedSourceIds: Array, - sources: Array, - onSelectedSourcesChange: (sourceIds: Array) => void, - filterText: string, -}; - -export default class ConsoleHeader extends React.Component { - _handleClearButtonClick = (event: SyntheticMouseEvent<>): void => { - this.props.clear(); - }; - - _handleCreatePasteButtonClick = (event: SyntheticMouseEvent<>): void => { - if (this.props.createPaste != null) { - this.props.createPaste(); - } - }; - - _handleFilterChange = (value: RegExpFilterChange): void => { - this.props.onFilterChange(value); - }; - - _renderProcessControlButton(source: Source): ?React.Element { - let action; - let label; - let icon; - switch (source.status) { - case 'starting': - case 'running': { - action = source.stop; - label = 'Stop Process'; - icon = 'primitive-square'; - break; - } - case 'stopped': { - action = source.start; - label = 'Start Process'; - icon = 'triangle-right'; - break; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _LoadingSpinner; + + + + + + + + + + + + + + +function _load_LoadingSpinner() {return _LoadingSpinner = require('nuclide-commons-ui/LoadingSpinner');} +var _react = _interopRequireWildcard(require('react'));var _ModalMultiSelect; +function _load_ModalMultiSelect() {return _ModalMultiSelect = require('nuclide-commons-ui/ModalMultiSelect');}var _RegExpFilter; +function _load_RegExpFilter() {return _RegExpFilter = _interopRequireDefault(require('nuclide-commons-ui/RegExpFilter'));}var _Toolbar; +function _load_Toolbar() {return _Toolbar = require('nuclide-commons-ui/Toolbar');}var _ToolbarLeft; +function _load_ToolbarLeft() {return _ToolbarLeft = require('nuclide-commons-ui/ToolbarLeft');}var _ToolbarRight; +function _load_ToolbarRight() {return _ToolbarRight = require('nuclide-commons-ui/ToolbarRight');}var _addTooltip; +function _load_addTooltip() {return _addTooltip = _interopRequireDefault(require('nuclide-commons-ui/addTooltip'));}var _Button; + +function _load_Button() {return _Button = require('nuclide-commons-ui/Button');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} + + + + + + + + + + + + + + +class ConsoleHeader extends _react.Component {constructor(...args) {var _temp;return _temp = super(...args), this. + _handleClearButtonClick = event => { + this.props.clear(); + }, this. + + _handleCreatePasteButtonClick = event => { + if (this.props.createPaste != null) { + this.props.createPaste(); } - } - if (action == null) { - return; - } - const clickHandler = event => { - event.stopPropagation(); - invariant(action != null); - action(); - }; - return ( - - ); - } - - _renderOption = (optionProps: { - option: {label: string, value: string}, - }): React.Element => { - const {option} = optionProps; - const source = this.props.sources.find(s => s.id === option.value); - invariant(source != null); - const startingSpinner = - source.status !== 'starting' ? null : ( - - ); - return ( - - {option.label} - {startingSpinner} - {this._renderProcessControlButton(source)} - - ); - }; - - render(): React.Node { - const options = this.props.sources - .slice() - .sort((a, b) => sortAlpha(a.name, b.name)) - .map(source => ({ - label: source.id, - value: source.name, - })); + }, this. + + _handleFilterChange = value => { + this.props.onFilterChange(value); + }, this. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _renderOption = optionProps => + + { + const { option } = optionProps; + const source = this.props.sources.find(s => s.id === option.value);if (!( + source != null)) {throw new Error('Invariant violation: "source != null"');} + const startingSpinner = + source.status !== 'starting' ? null : + _react.createElement((_LoadingSpinner || _load_LoadingSpinner()).LoadingSpinner, { + className: 'inline-block console-process-starting-spinner', + size: 'EXTRA_SMALL' }); + + + return ( + _react.createElement('span', null, + option.label, + startingSpinner, + this._renderProcessControlButton(source))); + + + }, _temp;}_renderProcessControlButton(source) {let action;let label;let icon;switch (source.status) {case 'starting':case 'running':{action = source.stop;label = 'Stop Process';icon = 'primitive-square';break;}case 'stopped':{action = source.start;label = 'Start Process';icon = 'triangle-right';break;}}if (action == null) {return;}const clickHandler = event => {event.stopPropagation();if (!(action != null)) {throw new Error('Invariant violation: "action != null"');}action();};return _react.createElement((_Button || _load_Button()).Button, { className: 'pull-right console-process-control-button', icon: icon, onClick: clickHandler }, label);} + + render() { + const options = this.props.sources. + slice(). + sort((a, b) => sortAlpha(a.name, b.name)). + map(source => ({ + label: source.id, + value: source.name })); + const sourceButton = - options.length === 0 ? null : ( - - ); + options.length === 0 ? null : + _react.createElement((_ModalMultiSelect || _load_ModalMultiSelect()).ModalMultiSelect, { + labelComponent: MultiSelectLabel, + optionComponent: this._renderOption, + size: (_Button || _load_Button()).ButtonSizes.SMALL, + options: options, + value: this.props.selectedSourceIds, + onChange: this.props.onSelectedSourcesChange, + className: 'inline-block' }); + + const pasteButton = - this.props.createPaste == null ? null : ( - - ); + this.props.createPaste == null ? null : + _react.createElement((_Button || _load_Button()).Button, { + className: 'inline-block', + size: (_Button || _load_Button()).ButtonSizes.SMALL, + onClick: this._handleCreatePasteButtonClick + // eslint-disable-next-line rulesdir/jsx-simple-callback-refs + , ref: (0, (_addTooltip || _load_addTooltip()).default)({ + title: 'Creates a Paste from the current contents of the console' }) }, 'Create Paste'); + + + + return ( - - - {sourceButton} - - - - {pasteButton} - - - - ); - } -} + invalid: this.props.invalidFilterInput }, + + onChange: this._handleFilterChange })), + + + _react.createElement((_ToolbarRight || _load_ToolbarRight()).ToolbarRight, null, + pasteButton, + _react.createElement((_Button || _load_Button()).Button, { + size: (_Button || _load_Button()).ButtonSizes.SMALL, + onClick: this._handleClearButtonClick }, 'Clear')))); + + -function sortAlpha(a: string, b: string): number { - const aLower = a.toLowerCase(); - const bLower = b.toLowerCase(); - if (aLower < bLower) { - return -1; - } else if (aLower > bLower) { - return 1; - } + + + }}exports.default = ConsoleHeader; /** + * 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. + * + * + * @format + */function sortAlpha(a, b) {const aLower = a.toLowerCase();const bLower = b.toLowerCase();if (aLower < bLower) {return -1;} else if (aLower > bLower) {return 1;} return 0; } -type LabelProps = { - selectedOptions: Array<{value: string, label: string}>, -}; -function MultiSelectLabel(props: LabelProps): React.Element { - const {selectedOptions} = props; + + + +function MultiSelectLabel(props) { + const { selectedOptions } = props; const label = - selectedOptions.length === 1 - ? selectedOptions[0].label - : `${selectedOptions.length} Sources`; - return Showing: {label}; -} + selectedOptions.length === 1 ? + selectedOptions[0].label : + `${selectedOptions.length} Sources`; + return _react.createElement('span', null, 'Showing: ', label); +} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/ConsoleView.js b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/ConsoleView.js index f469f08d..8119d223 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/ConsoleView.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/ConsoleView.js @@ -1,376 +1,393 @@ -/** - * 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 - * @format - */ - -import type { - DisplayableRecord, - Executor, - OutputProvider, - RecordHeightChangeHandler, - Source, - WatchEditorFunction, -} from '../types'; -import type {RegExpFilterChange} from 'nuclide-commons-ui/RegExpFilter'; - -import {macrotask} from 'nuclide-commons/observable'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import debounce from 'nuclide-commons/debounce'; -import * as React from 'react'; -import {Observable} from 'rxjs'; -import FilteredMessagesReminder from './FilteredMessagesReminder'; -import OutputTable from './OutputTable'; -import ConsoleHeader from './ConsoleHeader'; -import InputArea from './InputArea'; -import PromptButton from './PromptButton'; -import NewMessagesNotification from './NewMessagesNotification'; -import invariant from 'assert'; -import shallowEqual from 'shallowequal'; -import recordsChanged from '../recordsChanged'; -import StyleSheet from 'nuclide-commons-ui/StyleSheet'; -import classnames from 'classnames'; - -type Props = { - displayableRecords: Array, - history: Array, - clearRecords: () => void, - createPaste: ?() => Promise, - watchEditor: ?WatchEditorFunction, - execute: (code: string) => void, - currentExecutor: ?Executor, - executors: Map, - invalidFilterInput: boolean, - enableRegExpFilter: boolean, - selectedSourceIds: Array, - selectExecutor: (executorId: string) => void, - selectSources: (sourceIds: Array) => void, - sources: Array, - updateFilter: (change: RegExpFilterChange) => void, - getProvider: (id: string) => ?OutputProvider, - onDisplayableRecordHeightChange: RecordHeightChangeHandler, - filteredRecordCount: number, - filterText: string, - resetAllFilters: () => void, - fontSize: number, -}; - -type State = { - unseenMessages: boolean, - promptBufferChanged: boolean, -}; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _observable; + + + + + + + + + + + + + + + + + + + + + +function _load_observable() {return _observable = require('nuclide-commons/observable');}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _debounce; +function _load_debounce() {return _debounce = _interopRequireDefault(require('nuclide-commons/debounce'));} +var _react = _interopRequireWildcard(require('react')); +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _FilteredMessagesReminder; +function _load_FilteredMessagesReminder() {return _FilteredMessagesReminder = _interopRequireDefault(require('./FilteredMessagesReminder'));}var _OutputTable; +function _load_OutputTable() {return _OutputTable = _interopRequireDefault(require('./OutputTable'));}var _ConsoleHeader; +function _load_ConsoleHeader() {return _ConsoleHeader = _interopRequireDefault(require('./ConsoleHeader'));}var _InputArea; +function _load_InputArea() {return _InputArea = _interopRequireDefault(require('./InputArea'));}var _PromptButton; +function _load_PromptButton() {return _PromptButton = _interopRequireDefault(require('./PromptButton'));}var _NewMessagesNotification; +function _load_NewMessagesNotification() {return _NewMessagesNotification = _interopRequireDefault(require('./NewMessagesNotification'));}var _shallowequal; + +function _load_shallowequal() {return _shallowequal = _interopRequireDefault(require('shallowequal'));}var _recordsChanged; +function _load_recordsChanged() {return _recordsChanged = _interopRequireDefault(require('../recordsChanged'));}var _StyleSheet; +function _load_StyleSheet() {return _StyleSheet = _interopRequireDefault(require('nuclide-commons-ui/StyleSheet'));}var _classnames; +function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + // Maximum time (ms) for the console to try scrolling to the bottom. -const MAXIMUM_SCROLLING_TIME = 3000; +const MAXIMUM_SCROLLING_TIME = 3000; /** + * 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. + * + * + * @format + */let count = 0;class ConsoleView extends _react.Component { + + + + + + + constructor(props) { + super(props);this. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -let count = 0; -export default class ConsoleView extends React.Component { - _disposables: UniversalDisposable; - _isScrolledNearBottom: boolean; - _id: number; - // Used when _scrollToBottom is called. The console optimizes message loading + + _getExecutor = id => { + return this.props.executors.get(id); + };this. + + _getProvider = id => { + return this.props.getProvider(id); + };this. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _executePrompt = code => { + this.props.execute(code); + // Makes the console to scroll to the bottom. + this._isScrolledNearBottom = true; + };this. + + _handleScroll = ( + offsetHeight, + scrollHeight, + scrollTop) => + { + this._handleScrollEnd(offsetHeight, scrollHeight, scrollTop); + };this. + + + + + + + + + + + + + + + + + + + + + + + + + _handleOutputTable = ref => { + this._outputTable = ref; + };this. + + _scrollToBottom = () => { + if (!this._outputTable) { + return; + } + + this._outputTable.scrollToBottom(); + + this.setState({ unseenMessages: false }); + };this. + + _startScrollToBottom = () => { + if (!this._continuouslyScrollToBottom) { + this._continuouslyScrollToBottom = true; + + this._scrollingThrottle = _rxjsBundlesRxMinJs.Observable.timer( + MAXIMUM_SCROLLING_TIME). + subscribe(() => { + this._stopScrollToBottom(); + }); + } + + this._scrollToBottom(); + };this. + + _stopScrollToBottom = () => { + this._continuouslyScrollToBottom = false; + if (this._scrollingThrottle != null) { + this._scrollingThrottle.unsubscribe(); + } + };this. + + _shouldScrollToBottom = () => { + return this._isScrolledNearBottom || this._continuouslyScrollToBottom; + };this.state = { unseenMessages: false, promptBufferChanged: false };this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default();this._isScrolledNearBottom = true;this._continuouslyScrollToBottom = false;this._handleScrollEnd = (0, (_debounce || _load_debounce()).default)(this._handleScrollEnd, 100);this._id = count++;} // Used when _scrollToBottom is called. The console optimizes message loading // so scrolling to the bottom once doesn't always scroll to the bottom since // more messages can be loaded after. - _continuouslyScrollToBottom: boolean; - _scrollingThrottle: ?rxjs$Subscription; - - _outputTable: ?OutputTable; - - constructor(props: Props) { - super(props); - this.state = { - unseenMessages: false, - promptBufferChanged: false, - }; - this._disposables = new UniversalDisposable(); - this._isScrolledNearBottom = true; - this._continuouslyScrollToBottom = false; - (this: any)._handleScrollEnd = debounce(this._handleScrollEnd, 100); - this._id = count++; - } - - componentDidMount(): void { - this._disposables.add( - // Wait for `` to render itself via react-virtualized before scrolling and - // re-measuring; Otherwise, the scrolled location will be inaccurate, preventing the Console - // from auto-scrolling. - macrotask.subscribe(() => { - this._startScrollToBottom(); - }), - () => { - if (this._scrollingThrottle != null) { - this._scrollingThrottle.unsubscribe(); - } - }, - ); - } - - componentWillUnmount(): void { - this._disposables.dispose(); - } - - componentDidUpdate(prevProps: Props): void { - // If records are added while we're scrolled to the bottom (or very very close, at least), + componentDidMount() {this._disposables.add( // Wait for `` to render itself via react-virtualized before scrolling and + // re-measuring; Otherwise, the scrolled location will be inaccurate, preventing the Console + // from auto-scrolling. + (_observable || _load_observable()).macrotask.subscribe(() => {this._startScrollToBottom();}), () => {if (this._scrollingThrottle != null) {this._scrollingThrottle.unsubscribe();}});}componentWillUnmount() {this._disposables.dispose();}componentDidUpdate(prevProps) {// If records are added while we're scrolled to the bottom (or very very close, at least), // automatically scroll. - if ( - this._isScrolledNearBottom && - recordsChanged( - prevProps.displayableRecords, - this.props.displayableRecords, - ) - ) { - this._startScrollToBottom(); - } - } - - _renderPromptButton(): React.Element { - invariant(this.props.currentExecutor != null); - const {currentExecutor} = this.props; - const options = Array.from(this.props.executors.values()).map(executor => ({ - id: executor.id, - label: executor.name, - })); - return ( - - ); - } - - _isScrolledToBottom( - offsetHeight: number, - scrollHeight: number, - scrollTop: number, - ): boolean { - return scrollHeight - (offsetHeight + scrollTop) < 5; - } - - componentWillReceiveProps(nextProps: Props): void { - // If the messages were cleared, hide the notification. - if (nextProps.displayableRecords.length === 0) { - this._isScrolledNearBottom = true; - this.setState({unseenMessages: false}); - } else if ( - // If we receive new messages after we've scrolled away from the bottom, show the "new - // messages" notification. - !this._isScrolledNearBottom && - recordsChanged( - this.props.displayableRecords, - nextProps.displayableRecords, - ) - ) { - this.setState({unseenMessages: true}); - } - } - - shouldComponentUpdate(nextProps: Props, nextState: State): boolean { - return ( - !shallowEqual(this.props, nextProps) || - !shallowEqual(this.state, nextState) - ); - } - - _getExecutor = (id: string): ?Executor => { - return this.props.executors.get(id); - }; - - _getProvider = (id: string): ?OutputProvider => { - return this.props.getProvider(id); - }; - - render(): React.Node { - return ( -
- ({ id: executor.id, label: executor.name }));return _react.createElement((_PromptButton || _load_PromptButton()).default, { value: currentExecutor.id, onChange: this.props.selectExecutor, options: options, children: currentExecutor.name });}_isScrolledToBottom(offsetHeight, scrollHeight, scrollTop) {return scrollHeight - (offsetHeight + scrollTop) < 5;}componentWillReceiveProps(nextProps) {// If the messages were cleared, hide the notification. + if (nextProps.displayableRecords.length === 0) {this._isScrolledNearBottom = true;this.setState({ unseenMessages: false });} else if ( // If we receive new messages after we've scrolled away from the bottom, show the "new + // messages" notification. + !this._isScrolledNearBottom && (0, (_recordsChanged || _load_recordsChanged()).default)(this.props.displayableRecords, nextProps.displayableRecords)) {this.setState({ unseenMessages: true });}}shouldComponentUpdate(nextProps, nextState) {return !(0, (_shallowequal || _load_shallowequal()).default)(this.props, nextProps) || !(0, (_shallowequal || _load_shallowequal()).default)(this.state, nextState);}render() {return _react.createElement('div', { className: 'console' }, _react.createElement((_StyleSheet || _load_StyleSheet()).default, { sourcePath: 'console-font-style', priority: -1, css: ` #console-font-size-${this._id} { font-size: ${this.props.fontSize}px; } - `} - /> - - {/* - We need an extra wrapper element here in order to have the new messages notification stick - to the bottom of the scrollable area (and not scroll with it). - - console-font-size is defined in main.js and updated via a user setting - */} -
-
- - =0.53.0) Flow suppress - ref={this._handleOutputTable} - displayableRecords={this.props.displayableRecords} - showSourceLabels={this.props.selectedSourceIds.length > 1} - fontSize={this.props.fontSize} - getExecutor={this._getExecutor} - getProvider={this._getProvider} - onScroll={this._handleScroll} - onDisplayableRecordHeightChange={ - this.props.onDisplayableRecordHeightChange - } - shouldScrollToBottom={this._shouldScrollToBottom} - /> - -
- {this._renderPrompt()} - {this._renderMultilineTip()} -
-
- ); - } - - _renderMultilineTip(): ?React.Element { - const {currentExecutor} = this.props; - if (currentExecutor == null) { - return; - } - const keyCombo = - process.platform === 'darwin' ? ( - // Option + Enter on Mac - ⌥ + ⏎ - ) : ( - // Shift + Enter on Windows and Linux. - Shift + Enter - ); - - return ( -
- Tip: {keyCombo} to insert a newline -
- ); - } - - _renderPrompt(): ?React.Element { - const {currentExecutor} = this.props; - if (currentExecutor == null) { - return; - } - return ( -
- {this._renderPromptButton()} - { - this.setState({promptBufferChanged: true}); - }} - /> -
- ); - } - - _executePrompt = (code: string): void => { - this.props.execute(code); - // Makes the console to scroll to the bottom. - this._isScrolledNearBottom = true; - }; - - _handleScroll = ( - offsetHeight: number, - scrollHeight: number, - scrollTop: number, - ): void => { - this._handleScrollEnd(offsetHeight, scrollHeight, scrollTop); - }; - - _handleScrollEnd( - offsetHeight: number, - scrollHeight: number, - scrollTop: number, - ): void { - const isScrolledToBottom = this._isScrolledToBottom( - offsetHeight, - scrollHeight, - scrollTop, - ); - - if (this._continuouslyScrollToBottom && !isScrolledToBottom) { - this._scrollToBottom(); - } else { - this._isScrolledNearBottom = isScrolledToBottom; - this._stopScrollToBottom(); - this.setState({ - unseenMessages: - this.state.unseenMessages && !this._isScrolledNearBottom, - }); - } - } - - _handleOutputTable = (ref: OutputTable): void => { - this._outputTable = ref; - }; - - _scrollToBottom = (): void => { - if (!this._outputTable) { - return; - } - - this._outputTable.scrollToBottom(); - - this.setState({unseenMessages: false}); - }; - - _startScrollToBottom = (): void => { - if (!this._continuouslyScrollToBottom) { - this._continuouslyScrollToBottom = true; - - this._scrollingThrottle = Observable.timer( - MAXIMUM_SCROLLING_TIME, - ).subscribe(() => { - this._stopScrollToBottom(); - }); - } - - this._scrollToBottom(); - }; - - _stopScrollToBottom = (): void => { - this._continuouslyScrollToBottom = false; - if (this._scrollingThrottle != null) { - this._scrollingThrottle.unsubscribe(); - } - }; - - _shouldScrollToBottom = (): boolean => { - return this._isScrolledNearBottom || this._continuouslyScrollToBottom; - }; -} + ` }), _react.createElement((_ConsoleHeader || _load_ConsoleHeader()).default, { clear: this.props.clearRecords, createPaste: this.props.createPaste, invalidFilterInput: this.props.invalidFilterInput, enableRegExpFilter: this.props.enableRegExpFilter, filterText: this.props.filterText, selectedSourceIds: this.props.selectedSourceIds, sources: this.props.sources, onFilterChange: this.props.updateFilter, onSelectedSourcesChange: this.props.selectSources }), _react.createElement('div', { className: 'console-body', id: 'console-font-size-' + this._id }, _react.createElement('div', { className: 'console-scroll-pane-wrapper' }, _react.createElement((_FilteredMessagesReminder || _load_FilteredMessagesReminder()).default, { filteredRecordCount: this.props.filteredRecordCount, onReset: this.props.resetAllFilters }), _react.createElement((_OutputTable || _load_OutputTable()).default // $FlowFixMe(>=0.53.0) Flow suppress + , { ref: this._handleOutputTable, displayableRecords: this.props.displayableRecords, showSourceLabels: this.props.selectedSourceIds.length > 1, fontSize: this.props.fontSize, getExecutor: this._getExecutor, getProvider: this._getProvider, onScroll: this._handleScroll, onDisplayableRecordHeightChange: this.props.onDisplayableRecordHeightChange, shouldScrollToBottom: this._shouldScrollToBottom }), _react.createElement((_NewMessagesNotification || _load_NewMessagesNotification()).default, { visible: this.state.unseenMessages, onClick: this._startScrollToBottom })), this._renderPrompt(), this._renderMultilineTip()));}_renderMultilineTip() {const { currentExecutor } = this.props;if (currentExecutor == null) {return;}const keyCombo = process.platform === 'darwin' ? // Option + Enter on Mac + _react.createElement('span', null, '\u2325 + \u23CE') : // Shift + Enter on Windows and Linux. + _react.createElement('span', null, 'Shift + Enter');return _react.createElement('div', { className: (0, (_classnames || _load_classnames()).default)('console-multiline-tip', this.state.promptBufferChanged ? 'console-multiline-tip-dim' : 'console-multiline-tip-not-dim') }, 'Tip: ', keyCombo, ' to insert a newline');}_renderPrompt() {const { currentExecutor } = this.props;if (currentExecutor == null) {return;}return _react.createElement('div', { className: 'console-prompt' }, this._renderPromptButton(), _react.createElement((_InputArea || _load_InputArea()).default, { scopeName: currentExecutor.scopeName, onSubmit: this._executePrompt, history: this.props.history, watchEditor: this.props.watchEditor, onDidTextBufferChange: () => {this.setState({ promptBufferChanged: true });} }));}_handleScrollEnd(offsetHeight, scrollHeight, scrollTop) {const isScrolledToBottom = this._isScrolledToBottom(offsetHeight, scrollHeight, scrollTop);if (this._continuouslyScrollToBottom && !isScrolledToBottom) {this._scrollToBottom();} else {this._isScrolledNearBottom = isScrolledToBottom;this._stopScrollToBottom();this.setState({ unseenMessages: this.state.unseenMessages && !this._isScrolledNearBottom });}}}exports.default = ConsoleView; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/FilteredMessagesReminder.js b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/FilteredMessagesReminder.js index 8a56f66b..07b18f48 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/FilteredMessagesReminder.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/FilteredMessagesReminder.js @@ -1,47 +1,56 @@ -/** - * 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 - * @format - */ - -import * as React from 'react'; - -type Props = { - filteredRecordCount: number, - onReset: () => void, -}; - -export default class FilteredMessagesReminder extends React.Component { - handleClick = (e: SyntheticEvent<>) => { - e.preventDefault(); - this.props.onReset(); - }; - - render(): React.Node { - const {filteredRecordCount} = this.props; +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react'));function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} + + + + + + +class FilteredMessagesReminder extends _react.Component {constructor(...args) {var _temp;return _temp = super(...args), this. + handleClick = e => { + e.preventDefault(); + this.props.onReset(); + }, _temp;} + + render() { + const { filteredRecordCount } = this.props; if (filteredRecordCount === 0) { return null; } return ( -
-
-
-            {filteredRecordCount}{' '}
-            {filteredRecordCount === 1 ? 'message is' : 'messages are'} hidden
-            by filters.
-          
-
- -
Show all messages.
-
-
- ); - } -} + _react.createElement('div', { className: 'console-filtered-reminder' }, + _react.createElement('div', { style: { flex: 1 } }, + _react.createElement('pre', null, + filteredRecordCount, ' ', + filteredRecordCount === 1 ? 'message is' : 'messages are', ' hidden by filters.')), + + + + _react.createElement('a', { href: '#', onClick: this.handleClick }, + _react.createElement('pre', null, 'Show all messages.')))); + + + + }}exports.default = FilteredMessagesReminder; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/InputArea.js b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/InputArea.js index 6e00c969..996fc0bd 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/InputArea.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/InputArea.js @@ -1,170 +1,169 @@ -/** - * 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 - * @format - */ - -import type {WatchEditorFunction} from '../types'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import {AtomTextEditor} from 'nuclide-commons-ui/AtomTextEditor'; -import {Observable} from 'rxjs'; - -type Props = { - onSubmit: (value: string) => mixed, - scopeName: ?string, - history: Array, - watchEditor: ?WatchEditorFunction, - onDidTextBufferChange?: (event: atom$AggregatedTextEditEvent) => mixed, -}; - -type State = { - historyIndex: number, - draft: string, -}; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _UniversalDisposable; + + + + + + + + + + + + +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));} +var _react = _interopRequireWildcard(require('react')); +var _reactDom = _interopRequireDefault(require('react-dom'));var _AtomTextEditor; +function _load_AtomTextEditor() {return _AtomTextEditor = require('nuclide-commons-ui/AtomTextEditor');} +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */ + + + const ENTER_KEY_CODE = 13; const UP_KEY_CODE = 38; const DOWN_KEY_CODE = 40; -export default class InputArea extends React.Component { - _keySubscription: ?rxjs$ISubscription; - _textEditorModel: ?atom$TextEditor; - - constructor(props: Props) { - super(props); - this.state = { - historyIndex: -1, - draft: '', - }; - } - - _submit = (): void => { - // Clear the text and trigger the `onSubmit` callback - const editor = this._textEditorModel; - if (editor == null) { - return; - } - - const text = editor.getText(); - if (text === '') { - return; - } - - editor.setText(''); // Clear the text field. - this.props.onSubmit(text); - this.setState({historyIndex: -1}); - }; - - _attachLabel = (editor: atom$TextEditor): IDisposable => { - const {watchEditor} = this.props; - const disposable = new UniversalDisposable(); - if (watchEditor) { - disposable.add(watchEditor(editor, ['nuclide-console'])); - } - return disposable; - }; - - _handleTextEditor = (component: ?AtomTextEditor): void => { - if (this._keySubscription) { - this._textEditorModel = null; - this._keySubscription.unsubscribe(); - } - if (component) { - this._textEditorModel = component.getModel(); - const el = ReactDOM.findDOMNode(component); - this._keySubscription = Observable.fromEvent(el, 'keydown').subscribe( - this._handleKeyDown, - ); - } - }; - - _handleKeyDown = (event: KeyboardEvent): void => { - const editor = this._textEditorModel; - // Detect AutocompletePlus menu element: https://git.io/vddLi - const isAutocompleteOpen = - document.querySelector('autocomplete-suggestion-list') != null; - if (editor == null) { - return; - } - if (event.which === ENTER_KEY_CODE) { - event.preventDefault(); - event.stopImmediatePropagation(); - - if (event.ctrlKey || event.altKey || event.shiftKey) { - editor.insertNewline(); +class InputArea extends _react.Component { + + + + constructor(props) { + super(props);this. + + + + + + + _submit = () => { + // Clear the text and trigger the `onSubmit` callback + const editor = this._textEditorModel; + if (editor == null) { return; } - this._submit(); - } else if ( - event.which === UP_KEY_CODE && - (editor.getLineCount() <= 1 || editor.getCursorBufferPosition().row === 0) - ) { - if (this.props.history.length === 0 || isAutocompleteOpen) { + const text = editor.getText(); + if (text === '') { return; } - event.preventDefault(); - event.stopImmediatePropagation(); - const historyIndex = Math.min( - this.state.historyIndex + 1, - this.props.history.length - 1, - ); - if (this.state.historyIndex === -1) { - this.setState({historyIndex, draft: editor.getText()}); - } else { - this.setState({historyIndex}); + + editor.setText(''); // Clear the text field. + this.props.onSubmit(text); + this.setState({ historyIndex: -1 }); + };this. + + _attachLabel = editor => { + const { watchEditor } = this.props; + const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + if (watchEditor) { + disposable.add(watchEditor(editor, ['nuclide-console'])); } - editor.setText( - this.props.history[this.props.history.length - historyIndex - 1], - ); - } else if ( - event.which === DOWN_KEY_CODE && - (editor.getLineCount() <= 1 || - editor.getCursorBufferPosition().row === editor.getLineCount() - 1) - ) { - if (this.props.history.length === 0 || isAutocompleteOpen) { + return disposable; + };this. + + _handleTextEditor = component => { + if (this._keySubscription) { + this._textEditorModel = null; + this._keySubscription.unsubscribe(); + } + if (component) { + this._textEditorModel = component.getModel(); + const el = _reactDom.default.findDOMNode(component); + this._keySubscription = _rxjsBundlesRxMinJs.Observable.fromEvent(el, 'keydown').subscribe( + this._handleKeyDown); + + } + };this. + + _handleKeyDown = event => { + const editor = this._textEditorModel; + // Detect AutocompletePlus menu element: https://git.io/vddLi + const isAutocompleteOpen = + document.querySelector('autocomplete-suggestion-list') != null; + if (editor == null) { return; } - event.preventDefault(); - event.stopImmediatePropagation(); - const historyIndex = Math.max(this.state.historyIndex - 1, -1); - this.setState({historyIndex}); - if (historyIndex === -1) { - editor.setText(this.state.draft); - } else { + if (event.which === ENTER_KEY_CODE) { + event.preventDefault(); + event.stopImmediatePropagation(); + + if (event.ctrlKey || event.altKey || event.shiftKey) { + editor.insertNewline(); + return; + } + + this._submit(); + } else if ( + event.which === UP_KEY_CODE && ( + editor.getLineCount() <= 1 || editor.getCursorBufferPosition().row === 0)) + { + if (this.props.history.length === 0 || isAutocompleteOpen) { + return; + } + event.preventDefault(); + event.stopImmediatePropagation(); + const historyIndex = Math.min( + this.state.historyIndex + 1, + this.props.history.length - 1); + + if (this.state.historyIndex === -1) { + this.setState({ historyIndex, draft: editor.getText() }); + } else { + this.setState({ historyIndex }); + } editor.setText( - this.props.history[this.props.history.length - historyIndex - 1], - ); + this.props.history[this.props.history.length - historyIndex - 1]); + + } else if ( + event.which === DOWN_KEY_CODE && ( + editor.getLineCount() <= 1 || + editor.getCursorBufferPosition().row === editor.getLineCount() - 1)) + { + if (this.props.history.length === 0 || isAutocompleteOpen) { + return; + } + event.preventDefault(); + event.stopImmediatePropagation(); + const historyIndex = Math.max(this.state.historyIndex - 1, -1); + this.setState({ historyIndex }); + if (historyIndex === -1) { + editor.setText(this.state.draft); + } else { + editor.setText( + this.props.history[this.props.history.length - historyIndex - 1]); + + } } - } - }; + };this.state = { historyIndex: -1, draft: '' };} - render(): React.Node { + render() { const grammar = - this.props.scopeName == null - ? null - : atom.grammars.grammarForScopeName(this.props.scopeName); + this.props.scopeName == null ? + null : + atom.grammars.grammarForScopeName(this.props.scopeName); return ( -
- -
- ); - } -} + _react.createElement('div', { className: 'console-input-wrapper' }, + _react.createElement((_AtomTextEditor || _load_AtomTextEditor()).AtomTextEditor, { + ref: this._handleTextEditor, + grammar: grammar, + gutterHidden: true, + autoGrow: true, + lineNumberGutterVisible: false, + onConfirm: this._submit, + onInitialized: this._attachLabel, + onDidTextBufferChange: this.props.onDidTextBufferChange }))); + + + + }}exports.default = InputArea; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/NewMessagesNotification.js b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/NewMessagesNotification.js index 8d6a9404..ab544f2b 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/NewMessagesNotification.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/NewMessagesNotification.js @@ -1,38 +1,37 @@ -/** - * 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 - * @format - */ - -import classnames from 'classnames'; -import * as React from 'react'; - -type Props = { - onClick: () => mixed, - visible: boolean, -}; - -export default class NewMessagesNotification extends React.Component { - render(): React.Node { - const className = classnames( - 'console-new-messages-notification', - 'badge', - 'badge-info', - { - visible: this.props.visible, - }, - ); +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _classnames; + + + + + + + + + + + +function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));} +var _react = _interopRequireWildcard(require('react'));function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */class NewMessagesNotification extends _react.Component {render() {const className = (0, (_classnames || _load_classnames()).default)('console-new-messages-notification', + 'badge', + 'badge-info', + { + visible: this.props.visible }); + + return ( -
- - New Messages -
- ); - } -} + _react.createElement('div', { className: className, onClick: this.props.onClick }, + _react.createElement('span', { className: 'console-new-messages-notification-icon icon icon-nuclicon-arrow-down' }), 'New Messages')); + + + + }}exports.default = NewMessagesNotification; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/OutputTable.js b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/OutputTable.js index 4bd9ac6a..6a610a58 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/OutputTable.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/OutputTable.js @@ -1,270 +1,273 @@ -/** - * 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 - * @format - */ - -import type { - DisplayableRecord, - Executor, - OutputProvider, - Record, - RecordHeightChangeHandler, -} from '../types'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import nullThrows from 'nullthrows'; -import {ResizeObservable} from 'nuclide-commons-ui/observable-dom'; -import Hasher from 'nuclide-commons/Hasher'; -import * as React from 'react'; -import List from 'react-virtualized/dist/commonjs/List'; -import {Subject} from 'rxjs'; -import RecordView from './RecordView'; -import recordsChanged from '../recordsChanged'; - -type Props = { - displayableRecords: Array, - showSourceLabels: boolean, - fontSize: number, - getExecutor: (id: string) => ?Executor, - getProvider: (id: string) => ?OutputProvider, - onScroll: ( - offsetHeight: number, - scrollHeight: number, - scrollTop: number, - ) => void, - onDisplayableRecordHeightChange: RecordHeightChangeHandler, - shouldScrollToBottom: () => boolean, -}; - -type State = { - width: number, - height: number, -}; - -type RowRendererParams = { - index: number, - key: string, - style: Object, - isScrolling: boolean, -}; - -type RowHeightParams = { - index: number, -}; - -/* eslint-disable react/no-unused-prop-types */ -type OnScrollParams = { - clientHeight: number, - scrollHeight: number, - scrollTop: number, -}; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _UniversalDisposable; + + + + + + + + + + + + + + + + + + + +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _nullthrows; +function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));}var _observableDom; +function _load_observableDom() {return _observableDom = require('nuclide-commons-ui/observable-dom');}var _Hasher; +function _load_Hasher() {return _Hasher = _interopRequireDefault(require('nuclide-commons/Hasher'));} +var _react = _interopRequireWildcard(require('react'));var _List; +function _load_List() {return _List = _interopRequireDefault(require('react-virtualized/dist/commonjs/List'));} +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _RecordView; +function _load_RecordView() {return _RecordView = _interopRequireDefault(require('./RecordView'));}var _recordsChanged; +function _load_recordsChanged() {return _recordsChanged = _interopRequireDefault(require('../recordsChanged'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /* eslint-enable react/no-unused-prop-types */ // The number of extra rows to render beyond what is visible -const OVERSCAN_COUNT = 5; - -export default class OutputTable extends React.Component { - _disposable: UniversalDisposable; - _hasher: Hasher; - // This is a from react-virtualized (untyped library) - _list: ?React.Element; - _wrapper: ?HTMLElement; - _renderedRecords: Map; - - // The currently rendered range. - _startIndex: number; - _stopIndex: number; - _refs: Subject; - - constructor(props: Props) { - super(props); - this._disposable = new UniversalDisposable(); - this._hasher = new Hasher(); - this._renderedRecords = new Map(); - this.state = { - width: 0, - height: 0, - }; - this._startIndex = 0; - this._stopIndex = 0; - this._refs = new Subject(); - this._disposable.add( - this._refs - .filter(Boolean) - .switchMap(node => new ResizeObservable(nullThrows(node)).mapTo(node)) - .subscribe(node => { - const {offsetHeight, offsetWidth} = nullThrows(node); - this._handleResize(offsetHeight, offsetWidth); - }), - ); - } - - componentDidUpdate(prevProps: Props, prevState: State): void { - if ( - this._list != null && - recordsChanged( - prevProps.displayableRecords, - this.props.displayableRecords, - ) - ) { - // $FlowIgnore Untyped react-virtualized List method - this._list.recomputeRowHeights(); - } - if (prevProps.fontSize !== this.props.fontSize) { - this._renderedRecords.forEach(recordView => - recordView.measureAndNotifyHeight(), - ); - } - } - - componentWillUnmount() { - this._disposable.dispose(); - } - - _handleRef = (node: ?HTMLElement) => { - this._refs.next(node); - }; - - render(): React.Node { - return ( -
- {this._containerRendered() ? ( - =0.53.0) Flow suppress - ref={this._handleListRef} - height={this.state.height} - width={this.state.width} - rowCount={this.props.displayableRecords.length} - rowHeight={this._getRowHeight} - rowRenderer={this._renderRow} - overscanRowCount={OVERSCAN_COUNT} - onScroll={this._onScroll} - onRowsRendered={this._handleListRender} - /> - ) : null} -
- ); - } - - _handleListRender = (opts: {startIndex: number, stopIndex: number}): void => { - this._startIndex = opts.startIndex; - this._stopIndex = opts.stopIndex; - }; - - scrollToBottom(): void { - if (this._list != null) { - // $FlowIgnore Untyped react-virtualized List method - this._list.scrollToRow(this.props.displayableRecords.length - 1); - } - } - - _getExecutor = (id: string): ?Executor => { - return this.props.getExecutor(id); - }; - - _getProvider = (id: string): ?OutputProvider => { - return this.props.getProvider(id); - }; - - _renderRow = (rowMetadata: RowRendererParams): React.Element => { - const {index, style} = rowMetadata; - const displayableRecord = this.props.displayableRecords[index]; - const {record} = displayableRecord; - return ( -
- from react-virtualized (untyped library) + + + + + constructor(props) { + super(props);this. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _handleRef = node => { + this._refs.next(node); + };this. + + + + + + + + + + + + + + + + + + + + + + + + + + _handleListRender = opts => { + this._startIndex = opts.startIndex; + this._stopIndex = opts.stopIndex; + };this. + + + + + + + + + _getExecutor = id => { + return this.props.getExecutor(id); + };this. + + _getProvider = id => { + return this.props.getProvider(id); + };this. + + _renderRow = rowMetadata => { + const { index, style } = rowMetadata; + const displayableRecord = this.props.displayableRecords[index]; + const { record } = displayableRecord; + return ( + _react.createElement('div', { + key: this._hasher.getHash(displayableRecord.record), + className: 'console-table-row-wrapper', + style: style }, + _react.createElement((_RecordView || _load_RecordView()).default // eslint-disable-next-line rulesdir/jsx-simple-callback-refs - ref={(view: ?RecordView) => { - if (view != null) { - this._renderedRecords.set(record, view); - } else { - this._renderedRecords.delete(record); - } - }} - getExecutor={this._getExecutor} - getProvider={this._getProvider} - displayableRecord={displayableRecord} - showSourceLabel={this.props.showSourceLabels} - onHeightChange={this._handleRecordHeightChange} - /> -
- ); - }; - - _containerRendered(): boolean { - return this.state.width !== 0 && this.state.height !== 0; - } - - _getRowHeight = ({index}: RowHeightParams): number => { - return this.props.displayableRecords[index].height; - }; - - _handleTableWrapper = (tableWrapper: HTMLElement): void => { - this._wrapper = tableWrapper; - }; - - _handleListRef = (listRef: React.Element): void => { - this._list = listRef; - }; - - _handleResize = (height: number, width: number): void => { - if (height === this.state.height && width === this.state.width) { - return; - } - this.setState({ - width, - height, - }); - - // When this component resizes, the inner records will - // also resize and potentially have their heights change - // So we measure all of their heights again here - this._renderedRecords.forEach(recordView => - recordView.measureAndNotifyHeight(), - ); - }; - - _handleRecordHeightChange = (recordId: number, newHeight: number): void => { - this.props.onDisplayableRecordHeightChange(recordId, newHeight, () => { - // The react-virtualized List component is provided the row heights - // through a function, so it has no way of knowing that a row's height - // has changed unless we explicitly notify it to recompute the heights. - if (this._list == null) { + , { ref: view => { + if (view != null) { + this._renderedRecords.set(record, view); + } else { + this._renderedRecords.delete(record); + } + }, + getExecutor: this._getExecutor, + getProvider: this._getProvider, + displayableRecord: displayableRecord, + showSourceLabel: this.props.showSourceLabels, + onHeightChange: this._handleRecordHeightChange }))); + + + + };this. + + + + + + _getRowHeight = ({ index }) => { + return this.props.displayableRecords[index].height; + };this. + + _handleTableWrapper = tableWrapper => { + this._wrapper = tableWrapper; + };this. + + _handleListRef = listRef => { + this._list = listRef; + };this. + + _handleResize = (height, width) => { + if (height === this.state.height && width === this.state.width) { return; } - // $FlowIgnore Untyped react-virtualized List component method - this._list.recomputeRowHeights(); - - // If we are already scrolled to the bottom, scroll to ensure that the scrollbar remains at - // the bottom. This is important not just for if the last record changes height through user - // interaction (e.g. expanding a debugger variable), but also because this is the mechanism - // through which the record's true initial height is reported. Therefore, we may have scrolled - // to the bottom, and only afterwards received its true height. In this case, it's important - // that we then scroll to the new bottom. - if (this.props.shouldScrollToBottom()) { - this.scrollToBottom(); - } - }); - }; - - _onScroll = ({ - clientHeight, - scrollHeight, - scrollTop, - }: OnScrollParams): void => { - this.props.onScroll(clientHeight, scrollHeight, scrollTop); - }; -} + this.setState({ + width, + height }); + + + // When this component resizes, the inner records will + // also resize and potentially have their heights change + // So we measure all of their heights again here + this._renderedRecords.forEach(recordView => + recordView.measureAndNotifyHeight()); + + };this. + + _handleRecordHeightChange = (recordId, newHeight) => { + this.props.onDisplayableRecordHeightChange(recordId, newHeight, () => { + // The react-virtualized List component is provided the row heights + // through a function, so it has no way of knowing that a row's height + // has changed unless we explicitly notify it to recompute the heights. + if (this._list == null) { + return; + } + // $FlowIgnore Untyped react-virtualized List component method + this._list.recomputeRowHeights(); + + // If we are already scrolled to the bottom, scroll to ensure that the scrollbar remains at + // the bottom. This is important not just for if the last record changes height through user + // interaction (e.g. expanding a debugger variable), but also because this is the mechanism + // through which the record's true initial height is reported. Therefore, we may have scrolled + // to the bottom, and only afterwards received its true height. In this case, it's important + // that we then scroll to the new bottom. + if (this.props.shouldScrollToBottom()) { + this.scrollToBottom(); + } + }); + };this. + + _onScroll = ({ + clientHeight, + scrollHeight, + scrollTop }) => + { + this.props.onScroll(clientHeight, scrollHeight, scrollTop); + };this._disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default();this._hasher = new (_Hasher || _load_Hasher()).default();this._renderedRecords = new Map();this.state = { width: 0, height: 0 };this._startIndex = 0;this._stopIndex = 0;this._refs = new _rxjsBundlesRxMinJs.Subject();this._disposable.add(this._refs.filter(Boolean).switchMap(node => new (_observableDom || _load_observableDom()).ResizeObservable((0, (_nullthrows || _load_nullthrows()).default)(node)).mapTo(node)).subscribe(node => {const { offsetHeight, offsetWidth } = (0, (_nullthrows || _load_nullthrows()).default)(node);this._handleResize(offsetHeight, offsetWidth);}));} // The currently rendered range. + componentDidUpdate(prevProps, prevState) {if (this._list != null && (0, (_recordsChanged || _load_recordsChanged()).default)(prevProps.displayableRecords, this.props.displayableRecords)) {// $FlowIgnore Untyped react-virtualized List method + this._list.recomputeRowHeights();}if (prevProps.fontSize !== this.props.fontSize) {this._renderedRecords.forEach(recordView => recordView.measureAndNotifyHeight());}}componentWillUnmount() {this._disposable.dispose();}render() {return _react.createElement('div', { className: 'console-table-wrapper native-key-bindings', ref: this._handleRef, tabIndex: '1' }, this._containerRendered() ? _react.createElement((_List || _load_List()).default // $FlowFixMe(>=0.53.0) Flow suppress + , { ref: this._handleListRef, height: this.state.height, width: this.state.width, rowCount: this.props.displayableRecords.length, rowHeight: this._getRowHeight, rowRenderer: this._renderRow, overscanRowCount: OVERSCAN_COUNT, onScroll: this._onScroll, onRowsRendered: this._handleListRender }) : null);}scrollToBottom() {if (this._list != null) {// $FlowIgnore Untyped react-virtualized List method + this._list.scrollToRow(this.props.displayableRecords.length - 1);}}_containerRendered() {return this.state.width !== 0 && this.state.height !== 0;}}exports.default = OutputTable; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/PromptButton.js b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/PromptButton.js index 3e44e2da..40390605 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/PromptButton.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/PromptButton.js @@ -1,60 +1,59 @@ -/** - * 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 - * @format - */ - -import invariant from 'assert'; -import * as React from 'react'; -import electron from 'electron'; - -const {remote} = electron; -invariant(remote != null); - -type PromptOption = { - id: string, - label: string, -}; - -type Props = { - value: string, - onChange: (value: string) => void, - children: ?any, - options: Array, -}; - -export default class PromptButton extends React.Component { - _disposables: IDisposable; - - render(): React.Node { - return ( - - {this.props.children} - - - ); - } - - _handleClick = (event: SyntheticMouseEvent<>): void => { - const currentWindow = remote.getCurrentWindow(); - const menu = new remote.Menu(); - // TODO: Sort alphabetically by label - this.props.options.forEach(option => { - menu.append( +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); + + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react')); +var _electron = _interopRequireDefault(require('electron'));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} + +const { remote } = _electron.default; /** + * 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. + * + * + * @format + */if (!(remote != null)) {throw new Error('Invariant violation: "remote != null"');} + + + + +class PromptButton extends _react.Component {constructor(...args) {var _temp;return _temp = super(...args), this. + + + + + + + + + + + + _handleClick = event => { + const currentWindow = remote.getCurrentWindow(); + const menu = new remote.Menu(); + // TODO: Sort alphabetically by label + this.props.options.forEach(option => { + menu.append( new remote.MenuItem({ type: 'checkbox', checked: this.props.value === option.id, label: option.label, - click: () => this.props.onChange(option.id), - }), - ); - }); - menu.popup(currentWindow, event.clientX, event.clientY); - }; -} + click: () => this.props.onChange(option.id) })); + + + }); + menu.popup(currentWindow, event.clientX, event.clientY); + }, _temp;}render() {return _react.createElement('span', { className: 'console-prompt-wrapper', onClick: this._handleClick }, _react.createElement('span', { className: 'console-prompt-label' }, this.props.children), _react.createElement('span', { className: 'icon icon-chevron-right' }));}}exports.default = PromptButton; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/RecordView.js b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/RecordView.js index df9b6f29..68b7a028 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/RecordView.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/lib/ui/RecordView.js @@ -1,223 +1,223 @@ -/** - * 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 - * @format - */ - -import type { - Level, - Record, - DisplayableRecord, - Executor, - OutputProvider, -} from '../types'; - -import type {RenderSegmentProps} from 'nuclide-commons-ui/Ansi'; - -import classnames from 'classnames'; -import {MeasuredComponent} from 'nuclide-commons-ui/MeasuredComponent'; -import * as React from 'react'; -import {LazyNestedValueComponent} from 'nuclide-commons-ui/LazyNestedValueComponent'; -import SimpleValueComponent from 'nuclide-commons-ui/SimpleValueComponent'; -import shallowEqual from 'shallowequal'; -import Ansi from 'nuclide-commons-ui/Ansi'; -import {TextRenderer} from 'nuclide-commons-ui/TextRenderer'; -import debounce from 'nuclide-commons/debounce'; -import {nextAnimationFrame} from 'nuclide-commons/observable'; -import parseText from '../parseText'; - -type Props = { - displayableRecord: DisplayableRecord, - showSourceLabel: boolean, - getExecutor: (id: string) => ?Executor, - getProvider: (id: string) => ?OutputProvider, - onHeightChange: (recordId: number, newHeight: number) => void, -}; - -const AnsiRenderSegment = ({key, style, content}: RenderSegmentProps) => ( - - {parseText(content)} - -); - -const ONE_DAY = 1000 * 60 * 60 * 24; -export default class RecordView extends React.Component { - _wrapper: ?HTMLElement; - _debouncedMeasureAndNotifyHeight: () => void; - _rafDisposable: ?rxjs$Subscription; - - constructor(props: Props) { +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _classnames; + + + + + + + + + + + + + + + + + + + + + +function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));}var _MeasuredComponent; +function _load_MeasuredComponent() {return _MeasuredComponent = require('nuclide-commons-ui/MeasuredComponent');} +var _react = _interopRequireWildcard(require('react'));var _LazyNestedValueComponent; +function _load_LazyNestedValueComponent() {return _LazyNestedValueComponent = require('nuclide-commons-ui/LazyNestedValueComponent');}var _SimpleValueComponent; +function _load_SimpleValueComponent() {return _SimpleValueComponent = _interopRequireDefault(require('nuclide-commons-ui/SimpleValueComponent'));}var _shallowequal; +function _load_shallowequal() {return _shallowequal = _interopRequireDefault(require('shallowequal'));}var _Ansi; +function _load_Ansi() {return _Ansi = _interopRequireDefault(require('nuclide-commons-ui/Ansi'));}var _TextRenderer; +function _load_TextRenderer() {return _TextRenderer = require('nuclide-commons-ui/TextRenderer');}var _debounce; +function _load_debounce() {return _debounce = _interopRequireDefault(require('nuclide-commons/debounce'));}var _observable; +function _load_observable() {return _observable = require('nuclide-commons/observable');}var _parseText; +function _load_parseText() {return _parseText = _interopRequireDefault(require('../parseText'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + + + + + + + + + +const AnsiRenderSegment = ({ key, style, content }) => +_react.createElement('span', { key: key, style: style }, + (0, (_parseText || _load_parseText()).default)(content)); /** + * 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. + * + * + * @format + */const ONE_DAY = 1000 * 60 * 60 * 24;class RecordView extends _react.Component {constructor(props) { super(props); // The MeasuredComponent can call this many times in quick succession as the // child components render, so we debounce it since we only want to know about // the height change once everything has settled down - (this: any)._debouncedMeasureAndNotifyHeight = debounce( - this.measureAndNotifyHeight, - 10, - ); - } - - componentDidMount() { - // We initially assume a height for the record. After it is actually + this. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + measureAndNotifyHeight = () => { + // This method is called after the necessary DOM mutations have + // already occurred, however it is possible that the updates have + // not been flushed to the screen. So the height change update + // is deferred until the rendering is complete so that + // this._wrapper.offsetHeight gives us the correct final height + if (this._rafDisposable != null) { + this._rafDisposable.unsubscribe(); + } + this._rafDisposable = (_observable || _load_observable()).nextAnimationFrame.subscribe(() => { + if (this._wrapper == null) { + return; + } + const { offsetHeight } = this._wrapper; + const { displayableRecord, onHeightChange } = this.props; + if (offsetHeight !== displayableRecord.height) { + onHeightChange(displayableRecord.id, offsetHeight); + } + }); + };this. + + _handleRecordWrapper = wrapper => { + this._wrapper = wrapper; + };this._debouncedMeasureAndNotifyHeight = (0, (_debounce || _load_debounce()).default)(this.measureAndNotifyHeight, 10);}componentDidMount() {// We initially assume a height for the record. After it is actually // rendered we need it to measure its actual height and report it - this.measureAndNotifyHeight(); - } - - componentWillUnmount() { - if (this._rafDisposable != null) { - this._rafDisposable.unsubscribe(); - } - } - - _renderContent(displayableRecord: DisplayableRecord): React.Element { - const {record} = displayableRecord; - if (record.kind === 'request') { - // TODO: We really want to use a text editor to render this so that we can get syntax + this.measureAndNotifyHeight();}componentWillUnmount() {if (this._rafDisposable != null) {this._rafDisposable.unsubscribe();}}_renderContent(displayableRecord) {const { record } = displayableRecord;if (record.kind === 'request') {// TODO: We really want to use a text editor to render this so that we can get syntax // highlighting, but they're just too expensive. Figure out a less-expensive way to get syntax // highlighting. - return
{record.text || ' '}
; - } else if (record.kind === 'response') { - const executor = this.props.getExecutor(record.sourceId); - return this._renderNestedValueComponent(displayableRecord, executor); - } else if (record.data != null) { - const provider = this.props.getProvider(record.sourceId); - return this._renderNestedValueComponent(displayableRecord, provider); - } else { - // If there's not text, use a space to make sure the row doesn't collapse. - const text = record.text || ' '; - - if (record.format === 'ansi') { - return {text}; - } - return
{parseText(text)}
; - } - } - - shouldComponentUpdate(nextProps: Props): boolean { - return !shallowEqual(this.props, nextProps); - } - - _renderNestedValueComponent( - displayableRecord: DisplayableRecord, - provider: ?OutputProvider | ?Executor, - ): React.Element { - const {record, expansionStateId} = displayableRecord; - const getProperties = provider == null ? null : provider.getProperties; - const type = record.data == null ? null : record.data.type; - const simpleValueComponent = getComponent(type); - return ( - - ); - } - - render(): React.Node { - const {displayableRecord} = this.props; - const {record} = displayableRecord; - const {level, kind, timestamp, sourceId} = record; - - const classNames = classnames('console-record', `level-${level || 'log'}`, { - request: kind === 'request', - response: kind === 'response', - }); - - const iconName = getIconName(record); - // flowlint-next-line sketchy-null-string:off - const icon = iconName ? : null; - const sourceLabel = this.props.showSourceLabel ? ( - - {sourceId} - - ) : null; - let renderedTimestamp; - if (timestamp != null) { - const timestampLabel = - Date.now() - timestamp > ONE_DAY - ? timestamp.toLocaleString() - : timestamp.toLocaleTimeString(); - renderedTimestamp = ( -
{timestampLabel}
- ); - } - return ( - - {/* $FlowFixMe(>=0.53.0) Flow suppress */} -
- {icon} -
- {displayableRecord.record.repeatCount > 1 && ( -
- {displayableRecord.record.repeatCount} -
- )} -
- {this._renderContent(displayableRecord)} -
-
- {sourceLabel} - {renderedTimestamp} -
-
- ); - } - - measureAndNotifyHeight = () => { - // This method is called after the necessary DOM mutations have - // already occurred, however it is possible that the updates have - // not been flushed to the screen. So the height change update - // is deferred until the rendering is complete so that - // this._wrapper.offsetHeight gives us the correct final height - if (this._rafDisposable != null) { - this._rafDisposable.unsubscribe(); - } - this._rafDisposable = nextAnimationFrame.subscribe(() => { - if (this._wrapper == null) { - return; - } - const {offsetHeight} = this._wrapper; - const {displayableRecord, onHeightChange} = this.props; - if (offsetHeight !== displayableRecord.height) { - onHeightChange(displayableRecord.id, offsetHeight); - } - }); - }; - - _handleRecordWrapper = (wrapper: HTMLElement) => { - this._wrapper = wrapper; - }; -} - -function getComponent(type: ?string): React.ComponentType { - switch (type) { - case 'text': - return props => TextRenderer(props.evaluationResult); - case 'boolean': + return _react.createElement('pre', null, record.text || ' ');} else if (record.kind === 'response') {const executor = this.props.getExecutor(record.sourceId);return this._renderNestedValueComponent(displayableRecord, executor);} else if (record.data != null) {const provider = this.props.getProvider(record.sourceId);return this._renderNestedValueComponent(displayableRecord, provider);} else {// If there's not text, use a space to make sure the row doesn't collapse. + const text = record.text || ' ';if (record.format === 'ansi') {return _react.createElement((_Ansi || _load_Ansi()).default, { renderSegment: AnsiRenderSegment }, text);}return _react.createElement('pre', null, (0, (_parseText || _load_parseText()).default)(text));}}shouldComponentUpdate(nextProps) {return !(0, (_shallowequal || _load_shallowequal()).default)(this.props, nextProps);}_renderNestedValueComponent(displayableRecord, provider) {const { record, expansionStateId } = displayableRecord;const getProperties = provider == null ? null : provider.getProperties;const type = record.data == null ? null : record.data.type;const simpleValueComponent = getComponent(type);return _react.createElement((_LazyNestedValueComponent || _load_LazyNestedValueComponent()).LazyNestedValueComponent, { className: 'console-lazy-nested-value', evaluationResult: record.data, fetchChildren: getProperties, simpleValueComponent: simpleValueComponent, shouldCacheChildren: true, expansionStateId: expansionStateId });}render() {const { displayableRecord } = this.props;const { record } = displayableRecord;const { level, kind, timestamp, sourceId } = record;const classNames = (0, (_classnames || _load_classnames()).default)('console-record', `level-${level || 'log'}`, { request: kind === 'request', response: kind === 'response' });const iconName = getIconName(record); // flowlint-next-line sketchy-null-string:off + const icon = iconName ? _react.createElement('span', { className: `icon icon-${iconName}` }) : null;const sourceLabel = this.props.showSourceLabel ? _react.createElement('span', { className: `console-record-source-label ${getHighlightClassName(level)}` }, sourceId) : null;let renderedTimestamp;if (timestamp != null) {const timestampLabel = Date.now() - timestamp > ONE_DAY ? timestamp.toLocaleString() : timestamp.toLocaleTimeString();renderedTimestamp = _react.createElement('div', { className: 'console-record-timestamp' }, timestampLabel);}return _react.createElement((_MeasuredComponent || _load_MeasuredComponent()).MeasuredComponent, { onMeasurementsChanged: this._debouncedMeasureAndNotifyHeight }, _react.createElement('div', { ref: this._handleRecordWrapper, className: classNames }, icon, _react.createElement('div', { className: 'console-record-content-wrapper' }, displayableRecord.record.repeatCount > 1 && _react.createElement('div', { className: 'console-record-duplicate-number' }, displayableRecord.record.repeatCount), _react.createElement('div', { className: 'console-record-content' }, this._renderContent(displayableRecord))), sourceLabel, renderedTimestamp));}}exports.default = RecordView;function getComponent(type) {switch (type) {case 'text':return props => (0, (_TextRenderer || _load_TextRenderer()).TextRenderer)(props.evaluationResult);case 'boolean': case 'string': case 'number': case 'object': default: - return SimpleValueComponent; - } + return (_SimpleValueComponent || _load_SimpleValueComponent()).default;} + } -function getHighlightClassName(level: Level): string { +function getHighlightClassName(level) { switch (level) { case 'info': return 'highlight-info'; @@ -228,17 +228,17 @@ function getHighlightClassName(level: Level): string { case 'error': return 'highlight-error'; default: - return 'highlight'; - } + return 'highlight';} + } -function getIconName(record: Record): ?string { +function getIconName(record) { switch (record.kind) { case 'request': return 'chevron-right'; case 'response': - return 'arrow-small-left'; - } + return 'arrow-small-left';} + switch (record.level) { case 'info': return 'info'; @@ -247,6 +247,6 @@ function getIconName(record: Record): ?string { case 'warning': return 'alert'; case 'error': - return 'stop'; - } -} + return 'stop';} + +} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/spec/Epics-spec.js b/modules/atom-ide-ui/pkg/atom-ide-console/spec/Epics-spec.js index 2a6f1143..78100077 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/spec/Epics-spec.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/spec/Epics-spec.js @@ -1,59 +1,69 @@ -/** - * 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 - * @format - */ - -import type {AppState} from '../lib/types'; - -import {ActionsObservable} from 'nuclide-commons/redux-observable'; -import * as Actions from '../lib/redux/Actions'; -import * as Epics from '../lib/redux/Epics'; -import invariant from 'assert'; -import {Observable} from 'rxjs'; +'use strict';var _reduxObservable; + + + + + + + + + + + + + +function _load_reduxObservable() {return _reduxObservable = require('nuclide-commons/redux-observable');}var _Actions; +function _load_Actions() {return _Actions = _interopRequireWildcard(require('../lib/redux/Actions'));}var _Epics; +function _load_Epics() {return _Epics = _interopRequireWildcard(require('../lib/redux/Epics'));} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} describe('Epics', () => { describe('registerOutputProviderEpic', () => { it('observes the status', () => { const mockStore = { dispatch: () => {}, - getState: () => (({}: any): AppState), - }; + getState: () => ({}) }; + let setStatus; const provider = { id: 'test', - messages: Observable.never(), + messages: _rxjsBundlesRxMinJs.Observable.never(), observeStatus: cb => { setStatus = cb; }, start: () => {}, - stop: () => {}, - }; - const actions = new ActionsObservable( - Observable.of(Actions.registerOutputProvider(provider)), - ); + stop: () => {} }; + + const actions = new (_reduxObservable || _load_reduxObservable()).ActionsObservable( + _rxjsBundlesRxMinJs.Observable.of((_Actions || _load_Actions()).registerOutputProvider(provider))); + let results = []; - Epics.registerRecordProviderEpic(actions, mockStore).subscribe( - results.push.bind(results), - ); - invariant(setStatus != null); + (_Epics || _load_Epics()).registerRecordProviderEpic(actions, mockStore).subscribe( + results.push.bind(results));if (!( + + setStatus != null)) {throw new Error('Invariant violation: "setStatus != null"');} setStatus('running'); setStatus('stopped'); setStatus('running'); - results = results.filter(action => action.type === Actions.UPDATE_STATUS); + results = results.filter(action => action.type === (_Actions || _load_Actions()).UPDATE_STATUS); expect(results.length).toBe(3); expect( - results.map(action => { - invariant(action.type === Actions.UPDATE_STATUS); - return action.payload.status; - }), - ).toEqual(['running', 'stopped', 'running']); + results.map(action => {if (!( + action.type === (_Actions || _load_Actions()).UPDATE_STATUS)) {throw new Error('Invariant violation: "action.type === Actions.UPDATE_STATUS"');} + return action.payload.status; + })). + toEqual(['running', 'stopped', 'running']); }); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/spec/Reducers-spec.js b/modules/atom-ide-ui/pkg/atom-ide-console/spec/Reducers-spec.js index febf34f8..ba3a0d7d 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/spec/Reducers-spec.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/spec/Reducers-spec.js @@ -1,214 +1,216 @@ -/** - * 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 - * @format - */ - -import type {Action, Executor} from '../lib/types'; - -import * as Actions from '../lib/redux/Actions'; -import Reducers from '../lib/redux/Reducers'; -import * as Immutable from 'immutable'; -import {Observable} from 'rxjs'; - -const emptyAppState = { - createPasteFunction: null, - currentExecutorId: null, - maxMessageCount: Number.POSITIVE_INFINITY, - executors: new Map(), - providers: new Map(), - providerStatuses: new Map(), - providerSubscriptions: new Map(), - records: Immutable.List(), - history: [], -}; - -describe('createStateStream', () => { - describe('RECORD_RECEIVED', () => { - let finalState; - let initialRecords; - - beforeEach(() => { - initialRecords = Immutable.List(); - const initialState = { - ...emptyAppState, - maxMessageCount: 2, - records: initialRecords, - }; - const actions = []; - for (let i = 0; i < 5; i++) { - actions.push({ - type: Actions.RECORD_RECEIVED, - payload: { - record: { - level: 'info', - text: i.toString(), - }, - }, - }); - } - finalState = ((actions: any): Array).reduce( - Reducers, - initialState, - ); - }); - - it('adds records', () => { - expect(finalState.records.size).toBeGreaterThan(0); - }); - - it('truncates the record list using `maxMessageCount`', () => { - expect(finalState.records.size).toBe(2); - }); - - it('truncates the least recent records', () => { - expect(finalState.records.map(record => record.text).toArray()).toEqual([ - '3', - '4', - ]); - }); - - it("doesn't mutate the original records list", () => { - expect(initialRecords.size).toBe(0); - }); - }); - - describe('REGISTER_SOURCE', () => { - let initialProviders; - let finalState; - - beforeEach(() => { - initialProviders = new Map(); - const initialState = { - ...emptyAppState, - providers: initialProviders, - }; - const actions = [ - { - type: Actions.REGISTER_SOURCE, - payload: { - source: { - id: 'test', - records: Observable.empty(), - }, - }, - }, - ]; - finalState = ((actions: any): Array).reduce( - Reducers, - initialState, - ); - }); - - it('adds providers to the registry', () => { - expect(finalState.providers.size).toBe(1); - }); - - it("doesn't mutate the original provider map", () => { - expect(initialProviders.size).toBe(0); - }); - }); - - describe('CLEAR_RECORDS', () => { - let initialRecords; - let finalState; - - beforeEach(() => { - initialRecords = Immutable.List([ - { - kind: 'message', - sourceId: 'Test', - level: 'info', - text: 'test', - scopeName: null, - timestamp: new Date('2017-01-01T12:34:56.789Z'), - data: null, - repeatCount: 1, - }, - ]); - const initialState = { - ...emptyAppState, - records: initialRecords, - }; - const actions = [{type: Actions.CLEAR_RECORDS}]; - finalState = actions.reduce(Reducers, initialState); - }); - - it('clears the records', () => { - expect(finalState.records.size).toBe(0); - }); - - it("doesn't mutate the original records list", () => { - expect(initialRecords.size).toBe(1); - }); - }); - - describe('executor registration', () => { - let dummyExecutor; - let initialExecutors; - let initialState; - let finalState; - - beforeEach(() => { - dummyExecutor = createDummyExecutor('a'); - initialExecutors = new Map([['a', dummyExecutor]]); - initialState = { - ...emptyAppState, - executors: initialExecutors, - }; - }); - - describe('REGISTER_EXECUTOR', () => { - beforeEach(() => { - const actions = [ - { - type: Actions.REGISTER_EXECUTOR, - payload: { - executor: createDummyExecutor('b'), - }, - }, - ]; - finalState = actions.reduce(Reducers, initialState); - }); - - it('adds an executor', () => { - expect(finalState.executors.size).toBe(2); - }); - - it("doesn't mutate the original executor map", () => { - expect(initialExecutors.size).toBe(1); - }); - }); - - describe('unregisterExecutor', () => { - beforeEach(() => { - const actions = [Actions.unregisterExecutor(dummyExecutor)]; - finalState = actions.reduce(Reducers, initialState); - }); - - it('removes an executor', () => { - expect(finalState.executors.size).toBe(0); - }); - - it("doesn't mutate the original executor map", () => { - expect(initialExecutors.size).toBe(1); - }); - }); - }); -}); - -export function createDummyExecutor(id: string): Executor { - return { - id, - name: id, - scopeName: 'text.plain', - send: (code: string) => {}, - output: Observable.create(observer => {}), - }; -} +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +createDummyExecutor = createDummyExecutor;var _Actions;function _load_Actions() {return _Actions = _interopRequireWildcard(require('../lib/redux/Actions'));}var _Reducers;function _load_Reducers() {return _Reducers = _interopRequireDefault(require('../lib/redux/Reducers'));}var _immutable;function _load_immutable() {return _immutable = _interopRequireWildcard(require('immutable'));}var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}const emptyAppState = { createPasteFunction: null, currentExecutorId: null, maxMessageCount: Number.POSITIVE_INFINITY, executors: new Map(), providers: new Map(), providerStatuses: new Map(), providerSubscriptions: new Map(), records: (_immutable || _load_immutable()).List(), history: [] }; /** + * 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. + * + * + * @format + */describe('createStateStream', () => {describe('RECORD_RECEIVED', () => {let finalState;let initialRecords;beforeEach(() => {initialRecords = (_immutable || _load_immutable()).List();const initialState = Object.assign({}, emptyAppState, { maxMessageCount: 2, records: initialRecords });const actions = [];for (let i = 0; i < 5; i++) {actions.push({ type: (_Actions || _load_Actions()).RECORD_RECEIVED, payload: { record: { level: 'info', text: i.toString() } } });}finalState = actions.reduce((_Reducers || _load_Reducers()).default, initialState);});it('adds records', () => {expect(finalState.records.size).toBeGreaterThan(0);});it('truncates the record list using `maxMessageCount`', () => {expect(finalState.records.size).toBe(2);});it('truncates the least recent records', () => {expect(finalState.records.map(record => record.text).toArray()).toEqual(['3', '4']);});it("doesn't mutate the original records list", () => {expect(initialRecords.size).toBe(0);});});describe('REGISTER_SOURCE', () => {let initialProviders;let finalState;beforeEach(() => {initialProviders = new Map();const initialState = Object.assign({}, emptyAppState, { providers: initialProviders });const actions = [{ type: (_Actions || _load_Actions()).REGISTER_SOURCE, payload: { source: { id: 'test', records: _rxjsBundlesRxMinJs.Observable.empty() } } }];finalState = actions.reduce((_Reducers || _load_Reducers()).default, initialState);});it('adds providers to the registry', () => {expect(finalState.providers.size).toBe(1);});it("doesn't mutate the original provider map", () => {expect(initialProviders.size).toBe(0);});});describe('CLEAR_RECORDS', () => {let initialRecords;let finalState;beforeEach(() => {initialRecords = (_immutable || _load_immutable()).List([{ kind: 'message', sourceId: 'Test', level: 'info', text: 'test', scopeName: null, timestamp: new Date('2017-01-01T12:34:56.789Z'), data: null, repeatCount: 1 }]);const initialState = Object.assign({}, emptyAppState, { records: initialRecords });const actions = [{ type: (_Actions || _load_Actions()).CLEAR_RECORDS }];finalState = actions.reduce((_Reducers || _load_Reducers()).default, initialState);});it('clears the records', () => {expect(finalState.records.size).toBe(0);});it("doesn't mutate the original records list", () => {expect(initialRecords.size).toBe(1);});});describe('executor registration', () => {let dummyExecutor;let initialExecutors;let initialState;let finalState;beforeEach(() => {dummyExecutor = createDummyExecutor('a');initialExecutors = new Map([['a', dummyExecutor]]);initialState = Object.assign({}, emptyAppState, { executors: initialExecutors });});describe('REGISTER_EXECUTOR', () => {beforeEach(() => {const actions = [{ type: (_Actions || _load_Actions()).REGISTER_EXECUTOR, payload: { executor: createDummyExecutor('b') } }];finalState = actions.reduce((_Reducers || _load_Reducers()).default, initialState);});it('adds an executor', () => {expect(finalState.executors.size).toBe(2);});it("doesn't mutate the original executor map", () => {expect(initialExecutors.size).toBe(1);});});describe('unregisterExecutor', () => {beforeEach(() => {const actions = [(_Actions || _load_Actions()).unregisterExecutor(dummyExecutor)];finalState = actions.reduce((_Reducers || _load_Reducers()).default, initialState);});it('removes an executor', () => {expect(finalState.executors.size).toBe(0);});it("doesn't mutate the original executor map", () => {expect(initialExecutors.size).toBe(1);});});});});function createDummyExecutor(id) {return { id, name: id, scopeName: 'text.plain', send: code => {}, output: _rxjsBundlesRxMinJs.Observable.create(observer => {}) };} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/spec/getCurrentExecutorId-spec.js b/modules/atom-ide-ui/pkg/atom-ide-console/spec/getCurrentExecutorId-spec.js index fb406fad..b44f3a20 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/spec/getCurrentExecutorId-spec.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/spec/getCurrentExecutorId-spec.js @@ -1,40 +1,40 @@ -/** - * 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 - * @format - */ - -import getCurrentExecutorId from '../lib/getCurrentExecutorId'; -import * as Immutable from 'immutable'; -import {createDummyExecutor} from './Reducers-spec'; +'use strict';var _getCurrentExecutorId; + + + + + + + + + + + +function _load_getCurrentExecutorId() {return _getCurrentExecutorId = _interopRequireDefault(require('../lib/getCurrentExecutorId'));}var _immutable; +function _load_immutable() {return _immutable = _interopRequireWildcard(require('immutable'));}var _ReducersSpec; +function _load_ReducersSpec() {return _ReducersSpec = require('./Reducers-spec');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} const baseAppState = { createPasteFunction: null, currentExecutorId: 'a', maxMessageCount: Number.POSITIVE_INFINITY, - executors: new Map([['a', createDummyExecutor('a')]]), + executors: new Map([['a', (0, (_ReducersSpec || _load_ReducersSpec()).createDummyExecutor)('a')]]), providers: new Map(), providerStatuses: new Map(), - records: Immutable.List(), - history: [], -}; - -describe('getCurrentExecutorId', () => { - it('gets the current executor', () => { - expect(getCurrentExecutorId(baseAppState)).toBe('a'); - }); + records: (_immutable || _load_immutable()).List(), + history: [] }; /** + * 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. + * + * + * @format + */describe('getCurrentExecutorId', () => {it('gets the current executor', () => {expect((0, (_getCurrentExecutorId || _load_getCurrentExecutorId()).default)(baseAppState)).toBe('a');});it('returns an executor even if the current id is null', () => {const appState = Object.assign({}, baseAppState, { + currentExecutorId: null }); - it('returns an executor even if the current id is null', () => { - const appState = { - ...baseAppState, - currentExecutorId: null, - }; - expect(getCurrentExecutorId(appState)).toBe('a'); + expect((0, (_getCurrentExecutorId || _load_getCurrentExecutorId()).default)(appState)).toBe('a'); }); -}); +}); \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-console/spec/parseText-spec.js b/modules/atom-ide-ui/pkg/atom-ide-console/spec/parseText-spec.js index a1d3bf7e..863b0f47 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-console/spec/parseText-spec.js +++ b/modules/atom-ide-ui/pkg/atom-ide-console/spec/parseText-spec.js @@ -1,20 +1,20 @@ -/** - * 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 - * @format - */ - -import parseText from '../lib/parseText'; +'use strict';var _parseText; + + + + + + + + + + + +function _load_parseText() {return _parseText = _interopRequireDefault(require('../lib/parseText'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} describe('parseText', () => { it('parses url pattern', () => { - const chunks = parseText('Message: https://facebook.com'); + const chunks = (0, (_parseText || _load_parseText()).default)('Message: https://facebook.com'); expect(chunks.length).toBe(3); expect(chunks[0]).toBe('Message: '); expect(chunks[2]).toBe(''); @@ -28,4 +28,14 @@ describe('parseText', () => { expect(reactElement.props.children).toBe('https://facebook.com'); } }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/DatatipComponent.js b/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/DatatipComponent.js index 2d420476..eafd0092 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/DatatipComponent.js +++ b/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/DatatipComponent.js @@ -1,81 +1,80 @@ -/** - * 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 - * @format - */ - -import type {Datatip} from './types'; - -import * as React from 'react'; - -import {maybeToString} from 'nuclide-commons/string'; -import MarkedStringDatatip from './MarkedStringDatatip'; - -export const DATATIP_ACTIONS = Object.freeze({ - PIN: 'PIN', - CLOSE: 'CLOSE', -}); - -const IconsForAction = { - [DATATIP_ACTIONS.PIN]: 'pin', - [DATATIP_ACTIONS.CLOSE]: 'x', -}; - -type DatatipComponentProps = { - action: string, - actionTitle: string, - className?: string, - datatip: Datatip, - onActionClick: Function, -}; - -export class DatatipComponent extends React.Component { - handleActionClick = (event: SyntheticEvent<>) => { - this.props.onActionClick(); - }; - - render(): React.Node { - const { - className, - action, - actionTitle, - datatip, - onActionClick, - ...props - } = this.props; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.DatatipComponent = exports.DATATIP_ACTIONS = undefined; + + + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react'));var _string; + +function _load_string() {return _string = require('nuclide-commons/string');}var _MarkedStringDatatip; +function _load_MarkedStringDatatip() {return _MarkedStringDatatip = _interopRequireDefault(require('./MarkedStringDatatip'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _objectWithoutProperties(obj, keys) {var target = {};for (var i in obj) {if (keys.indexOf(i) >= 0) continue;if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;target[i] = obj[i];}return target;} /** + * 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. + * + * + * @format + */const DATATIP_ACTIONS = exports.DATATIP_ACTIONS = Object.freeze({ PIN: 'PIN', CLOSE: 'CLOSE' });const IconsForAction = { [DATATIP_ACTIONS.PIN]: 'pin', [DATATIP_ACTIONS.CLOSE]: 'x' }; + + + + + + + + + +class DatatipComponent extends _react.Component {constructor(...args) {var _temp;return _temp = super(...args), this. + handleActionClick = event => { + this.props.onActionClick(); + }, _temp;} + + render() { + const _props = + + + + + + + this.props,{ className, action, actionTitle, datatip, onActionClick } = _props,props = _objectWithoutProperties(_props, ['className', 'action', 'actionTitle', 'datatip', 'onActionClick']); let content; if (datatip.component != null) { - content = ; + content = _react.createElement(datatip.component, null); } else if (datatip.markedStrings != null) { - content = ; + content = _react.createElement((_MarkedStringDatatip || _load_MarkedStringDatatip()).default, { markedStrings: datatip.markedStrings }); } let actionButton = null; if (action != null && IconsForAction[action] != null) { const actionIcon = IconsForAction[action]; - actionButton = ( -
- ); + actionButton = + _react.createElement('div', { + className: `datatip-pin-button icon-${actionIcon}`, + onClick: this.handleActionClick, + title: actionTitle }); + + } return ( -
-
{content}
- {actionButton} -
- ); - } -} + _react.createElement('div', Object.assign({ + className: `${(0, (_string || _load_string()).maybeToString)(className)} datatip-container` }, + props), + _react.createElement('div', { className: 'datatip-content' }, content), + actionButton)); + + + }}exports.DatatipComponent = DatatipComponent; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/DatatipManager.js b/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/DatatipManager.js index 718f999f..23f817c1 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/DatatipManager.js +++ b/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/DatatipManager.js @@ -1,229 +1,229 @@ -/** - * 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 - * @format - */ - -/* global performance */ - -import type { - AnyDatatipProvider, - Datatip, - DatatipProvider, - ModifierDatatipProvider, - ModifierKey, - PinnedDatatipOptions, -} from './types'; - -import {Range} from 'atom'; -import {asyncFind} from 'nuclide-commons/promise'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import analytics from 'nuclide-commons/analytics'; -import debounce from 'nuclide-commons/debounce'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import idx from 'idx'; -import performanceNow from 'nuclide-commons/performanceNow'; -import {Observable} from 'rxjs'; -import {getLogger} from 'log4js'; -import ProviderRegistry from 'nuclide-commons-atom/ProviderRegistry'; -import {observeTextEditors} from 'nuclide-commons-atom/text-editor'; -import { - getModifierKeysFromMouseEvent, - getModifierKeyFromKeyboardEvent, -} from './getModifierKeys'; - -import {DatatipComponent, DATATIP_ACTIONS} from './DatatipComponent'; -import isScrollable from './isScrollable'; -import {PinnedDatatip} from './PinnedDatatip'; - -const DEFAULT_DATATIP_DEBOUNCE_DELAY = 1000; -const DEFAULT_DATATIP_INTERACTED_DEBOUNCE_DELAY = 1000; - -type PinClickHandler = (editor: atom$TextEditor, datatip: Datatip) => void; - -type DatatipResult = { - datatip: Datatip, - provider: AnyDatatipProvider, -}; - -function getProviderName(provider: AnyDatatipProvider): string { - if (provider.providerName == null) { - getLogger('datatip').error('Datatip provider has no name', provider); - return 'unknown'; - } - return provider.providerName; -} +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.DatatipManager = undefined;var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));let getDatatipResults = (() => {var _ref5 = (0, _asyncToGenerator.default)( -function getBufferPosition( - editor: TextEditor, - editorView: atom$TextEditorElement, - event: ?MouseEvent, -): null | atom$Point { - if (!event) { - return null; - } - const text = editorView.component; - if (!text) { - return null; - } - const screenPosition = text.screenPositionForMouseEvent(event); - const pixelPosition = text.pixelPositionForMouseEvent(event); - const pixelPositionFromScreenPosition = text.pixelPositionForScreenPosition( - screenPosition, - ); - // Distance (in pixels) between screenPosition and the cursor. - const horizontalDistance = - pixelPosition.left - pixelPositionFromScreenPosition.left; - // `screenPositionForMouseEvent.column` cannot exceed the current line length. - // This is essentially a heuristic for "mouse cursor is to the left or right - // of text content". - if ( - pixelPosition.left <= 0 || - horizontalDistance > editor.getDefaultCharWidth() - ) { - return null; - } - return editor.bufferPositionForScreenPosition(screenPosition); -} -async function getDatatipResults( - providers: ProviderRegistry, - editor: atom$TextEditor, - position: atom$Point, - invoke: TProvider => Promise, -): Promise> { - const filteredDatatipProviders = Array.from( - providers.getAllProvidersForEditor(editor), - ); - if (filteredDatatipProviders.length === 0) { - return []; - } - const promises = filteredDatatipProviders.map( - async (provider: TProvider): Promise => { - const name = getProviderName(provider); - const timingTracker = new analytics.TimingTracker(name + '.datatip', {}); - try { - const datatip: ?Datatip = await invoke(provider); - if (!datatip) { - return null; - } - timingTracker.onSuccess(); - const result: DatatipResult = { - datatip, - provider, - }; - return result; - } catch (e) { - timingTracker.onError(e); - getLogger('datatip').error( - `Error getting datatip from provider ${name}`, - e, - ); - return null; - } - }, - ); - if (featureConfig.get('atom-ide-datatip.onlyTopDatatip')) { - const result = await asyncFind(promises, x => x); - return result != null ? [result] : []; - } else { - return (await Promise.all(promises)).filter(Boolean); - } -} -type PinnableDatatipProps = { - datatip: Datatip, - editor: atom$TextEditor, - onPinClick: PinClickHandler, -}; -function PinnableDatatip({ - datatip, + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + function* ( + providers, editor, - onPinClick, -}: PinnableDatatipProps): React.Element { - let action; - let actionTitle; + position, + invoke) + { + const filteredDatatipProviders = Array.from( + providers.getAllProvidersForEditor(editor)); + + if (filteredDatatipProviders.length === 0) { + return []; + } + + const promises = filteredDatatipProviders.map((() => {var _ref6 = (0, _asyncToGenerator.default)( + function* (provider) { + const name = getProviderName(provider); + const timingTracker = new (_analytics || _load_analytics()).default.TimingTracker(name + '.datatip', {}); + try { + const datatip = yield invoke(provider); + if (!datatip) { + return null; + } + + timingTracker.onSuccess(); + + const result = { + datatip, + provider }; + + return result; + } catch (e) { + timingTracker.onError(e); + (0, (_log4js || _load_log4js()).getLogger)('datatip').error( + `Error getting datatip from provider ${name}`, + e); + + return null; + } + });return function (_x5) {return _ref6.apply(this, arguments);};})()); + + if ((_featureConfig || _load_featureConfig()).default.get('atom-ide-datatip.onlyTopDatatip')) { + const result = yield (0, (_promise || _load_promise()).asyncFind)(promises, function (x) {return x;}); + return result != null ? [result] : []; + } else { + return (yield Promise.all(promises)).filter(Boolean); + } + });return function getDatatipResults(_x, _x2, _x3, _x4) {return _ref5.apply(this, arguments);};})();var _atom = require('atom');var _promise;function _load_promise() {return _promise = require('nuclide-commons/promise');}var _react = _interopRequireWildcard(require('react'));var _reactDom = _interopRequireDefault(require('react-dom'));var _UniversalDisposable;function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _analytics;function _load_analytics() {return _analytics = _interopRequireDefault(require('nuclide-commons/analytics'));}var _debounce;function _load_debounce() {return _debounce = _interopRequireDefault(require('nuclide-commons/debounce'));}var _featureConfig;function _load_featureConfig() {return _featureConfig = _interopRequireDefault(require('nuclide-commons-atom/feature-config'));}var _idx;function _load_idx() {return _idx = _interopRequireDefault(require('idx'));}var _performanceNow;function _load_performanceNow() {return _performanceNow = _interopRequireDefault(require('nuclide-commons/performanceNow'));}var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _log4js;function _load_log4js() {return _log4js = require('log4js');}var _ProviderRegistry;function _load_ProviderRegistry() {return _ProviderRegistry = _interopRequireDefault(require('nuclide-commons-atom/ProviderRegistry'));}var _textEditor;function _load_textEditor() {return _textEditor = require('nuclide-commons-atom/text-editor');}var _getModifierKeys;function _load_getModifierKeys() {return _getModifierKeys = require('./getModifierKeys');}var _DatatipComponent;function _load_DatatipComponent() {return _DatatipComponent = require('./DatatipComponent');}var _isScrollable;function _load_isScrollable() {return _isScrollable = _interopRequireDefault(require('./isScrollable'));}var _PinnedDatatip;function _load_PinnedDatatip() {return _PinnedDatatip = require('./PinnedDatatip');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}const DEFAULT_DATATIP_DEBOUNCE_DELAY = 1000; /** + * 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. + * + * + * @format + */ /* global performance */const DEFAULT_DATATIP_INTERACTED_DEBOUNCE_DELAY = 1000;function getProviderName(provider) {if (provider.providerName == null) {(0, (_log4js || _load_log4js()).getLogger)('datatip').error('Datatip provider has no name', provider);return 'unknown';}return provider.providerName;}function getBufferPosition(editor, editorView, event) {if (!event) {return null;}const text = editorView.component;if (!text) {return null;}const screenPosition = text.screenPositionForMouseEvent(event);const pixelPosition = text.pixelPositionForMouseEvent(event);const pixelPositionFromScreenPosition = text.pixelPositionForScreenPosition(screenPosition); // Distance (in pixels) between screenPosition and the cursor. + const horizontalDistance = pixelPosition.left - pixelPositionFromScreenPosition.left; // `screenPositionForMouseEvent.column` cannot exceed the current line length. + // This is essentially a heuristic for "mouse cursor is to the left or right + // of text content". + if (pixelPosition.left <= 0 || horizontalDistance > editor.getDefaultCharWidth()) {return null;}return editor.bufferPositionForScreenPosition(screenPosition);}function PinnableDatatip({ datatip, editor, onPinClick }) {let action;let actionTitle; // Datatips are pinnable by default, unless explicitly specified // otherwise. if (datatip.pinnable !== false) { - action = DATATIP_ACTIONS.PIN; + action = (_DatatipComponent || _load_DatatipComponent()).DATATIP_ACTIONS.PIN; actionTitle = 'Pin this Datatip'; } return ( // $FlowFixMe(>=0.53.0) Flow suppress - onPinClick(editor, datatip)} - /> - ); + _react.createElement((_DatatipComponent || _load_DatatipComponent()).DatatipComponent, { + action: action, + actionTitle: actionTitle, + datatip: datatip, + onActionClick: () => onPinClick(editor, datatip) })); + + } function mountDatatipWithMarker( - editor: atom$TextEditor, - element: HTMLElement, - range: atom$Range, - renderedProviders: React.Element, - position: atom$Point, -): IDisposable { +editor, +element, +range, +renderedProviders, +position) +{ // Highlight the text indicated by the datatip's range. const highlightMarker = editor.markBufferRange(range, { - invalidate: 'never', - }); + invalidate: 'never' }); + editor.decorateMarker(highlightMarker, { type: 'highlight', - class: 'datatip-highlight-region', - }); + class: 'datatip-highlight-region' }); + // The actual datatip should appear at the trigger position. - const overlayMarker = editor.markBufferRange(new Range(position, position), { - invalidate: 'never', - }); + const overlayMarker = editor.markBufferRange(new _atom.Range(position, position), { + invalidate: 'never' }); + editor.decorateMarker(overlayMarker, { type: 'overlay', position: 'tail', - item: element, - }); - - return new UniversalDisposable( - () => highlightMarker.destroy(), - () => overlayMarker.destroy(), - // The editor may not mount the marker until the next update. - // It's not safe to render anything until that point, as datatips - // often need to measure their size in the DOM. - Observable.from(editor.getElement().getNextUpdatePromise()).subscribe( - () => { - element.style.display = 'block'; - ReactDOM.render(renderedProviders, element); - }, - ), - ); + item: element }); + + + return new (_UniversalDisposable || _load_UniversalDisposable()).default( + () => highlightMarker.destroy(), + () => overlayMarker.destroy(), + // The editor may not mount the marker until the next update. + // It's not safe to render anything until that point, as datatips + // often need to measure their size in the DOM. + _rxjsBundlesRxMinJs.Observable.from(editor.getElement().getNextUpdatePromise()).subscribe( + () => { + element.style.display = 'block'; + _reactDom.default.render(renderedProviders, element); + })); + + } const DatatipState = Object.freeze({ HIDDEN: 'HIDDEN', FETCHING: 'FETCHING', - VISIBLE: 'VISIBLE', -}); -type State = $Keys; + VISIBLE: 'VISIBLE' }); + + -function ensurePositiveNumber(value: any, defaultValue: number): number { +function ensurePositiveNumber(value, defaultValue) { if (typeof value !== 'number' || value < 0) { return defaultValue; } @@ -231,40 +231,40 @@ function ensurePositiveNumber(value: any, defaultValue: number): number { } class DatatipManagerForEditor { - _blacklistedPosition: ?atom$Point; - _datatipElement: HTMLElement; - _datatipProviders: ProviderRegistry; - _modifierDatatipProviders: ProviderRegistry; - _datatipState: State; - _editor: atom$TextEditor; - _editorView: atom$TextEditorElement; - _insideDatatip: boolean; - _lastHiddenTime: number; - _lastFetchedFromCursorPosition: boolean; - _lastMoveEvent: ?MouseEvent; - _lastPosition: ?atom$Point; - _lastResultsPromise: ?Promise>; - _heldKeys: Set; - _markerDisposable: ?IDisposable; - _pinnedDatatips: Set; - _range: ?atom$Range; - _shouldDropNextMouseMoveAfterFocus: boolean; - _startFetchingDebounce: () => void; - _hideIfOutsideDebounce: () => void; - _subscriptions: UniversalDisposable; - _interactedWith: boolean; - _checkedScrollable: boolean; - _isScrollable: boolean; + + + + + + + + + + + + + + + + + + + + + + + + constructor( - editor: atom$TextEditor, - datatipProviders: ProviderRegistry, - modifierDatatipProviders: ProviderRegistry, - ) { + editor, + datatipProviders, + modifierDatatipProviders) + {_initialiseProps.call(this); this._editor = editor; this._editorView = atom.views.getView(editor); this._pinnedDatatips = new Set(); - this._subscriptions = new UniversalDisposable(); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._datatipProviders = datatipProviders; this._modifierDatatipProviders = modifierDatatipProviders; this._datatipElement = document.createElement('div'); @@ -279,125 +279,125 @@ class DatatipManagerForEditor { this._shouldDropNextMouseMoveAfterFocus = false; this._subscriptions.add( - featureConfig.observe('atom-ide-datatip.datatipDebounceDelay', () => - this._setStartFetchingDebounce(), - ), - featureConfig.observe( - 'atom-ide-datatip.datatipInteractedWithDebounceDelay', - () => this._setHideIfOutsideDebounce(), - ), - Observable.fromEvent(this._editorView, 'focus').subscribe(e => { - this._shouldDropNextMouseMoveAfterFocus = true; - if (!this._insideDatatip) { - this._setState(DatatipState.HIDDEN); - } - }), - Observable.fromEvent(this._editorView, 'blur').subscribe(e => { - if (!this._insideDatatip) { - this._setState(DatatipState.HIDDEN); - } - }), - Observable.fromEvent(this._editorView, 'mousemove').subscribe(e => { - this._lastFetchedFromCursorPosition = false; - if (this._shouldDropNextMouseMoveAfterFocus) { - this._shouldDropNextMouseMoveAfterFocus = false; - return; - } + (_featureConfig || _load_featureConfig()).default.observe('atom-ide-datatip.datatipDebounceDelay', () => + this._setStartFetchingDebounce()), - this._lastMoveEvent = e; - this._heldKeys = getModifierKeysFromMouseEvent(e); - if (this._datatipState === DatatipState.HIDDEN) { - this._startFetchingDebounce(); - } else { - this._hideIfOutside(); - } - }), - Observable.fromEvent(this._editorView, 'mouseleave').subscribe(() => { - this._lastMoveEvent = null; + (_featureConfig || _load_featureConfig()).default.observe( + 'atom-ide-datatip.datatipInteractedWithDebounceDelay', + () => this._setHideIfOutsideDebounce()), + + _rxjsBundlesRxMinJs.Observable.fromEvent(this._editorView, 'focus').subscribe(e => { + this._shouldDropNextMouseMoveAfterFocus = true; + if (!this._insideDatatip) { + this._setState(DatatipState.HIDDEN); + } + }), + _rxjsBundlesRxMinJs.Observable.fromEvent(this._editorView, 'blur').subscribe(e => { + if (!this._insideDatatip) { + this._setState(DatatipState.HIDDEN); + } + }), + _rxjsBundlesRxMinJs.Observable.fromEvent(this._editorView, 'mousemove').subscribe(e => { + this._lastFetchedFromCursorPosition = false; + if (this._shouldDropNextMouseMoveAfterFocus) { + this._shouldDropNextMouseMoveAfterFocus = false; + return; + } + + this._lastMoveEvent = e; + this._heldKeys = (0, (_getModifierKeys || _load_getModifierKeys()).getModifierKeysFromMouseEvent)(e); + if (this._datatipState === DatatipState.HIDDEN) { + this._startFetchingDebounce(); + } else { this._hideIfOutside(); - }), - Observable.fromEvent(this._editorView, 'mousedown').subscribe(e => { - let node = e.target; - while (node != null) { - if (node === this._datatipElement) { - return; - } - node = node.parentNode; + } + }), + _rxjsBundlesRxMinJs.Observable.fromEvent(this._editorView, 'mouseleave').subscribe(() => { + this._lastMoveEvent = null; + this._hideIfOutside(); + }), + _rxjsBundlesRxMinJs.Observable.fromEvent(this._editorView, 'mousedown').subscribe(e => { + let node = e.target; + while (node != null) { + if (node === this._datatipElement) { + return; } + node = node.parentNode; + } - this._hideOrCancel(); - }), - Observable.fromEvent(this._editorView, 'keydown').subscribe(e => { - const modifierKey = getModifierKeyFromKeyboardEvent(e); - if (modifierKey) { - // On Windows, key repeat applies to modifier keys too! - // So it's quite possible that we hit this twice without hitting keyup. - if (this._heldKeys.has(modifierKey)) { - return; - } - this._heldKeys.add(modifierKey); - if (this._datatipState !== DatatipState.HIDDEN) { - this._fetchInResponseToKeyPress(); - } - } else { - this._hideOrCancel(); - } - }), - Observable.fromEvent(this._editorView, 'keyup').subscribe(e => { - const modifierKey = getModifierKeyFromKeyboardEvent(e); - if (modifierKey) { - this._heldKeys.delete(modifierKey); - if (this._datatipState !== DatatipState.HIDDEN) { - this._fetchInResponseToKeyPress(); - } + this._hideOrCancel(); + }), + _rxjsBundlesRxMinJs.Observable.fromEvent(this._editorView, 'keydown').subscribe(e => { + const modifierKey = (0, (_getModifierKeys || _load_getModifierKeys()).getModifierKeyFromKeyboardEvent)(e); + if (modifierKey) { + // On Windows, key repeat applies to modifier keys too! + // So it's quite possible that we hit this twice without hitting keyup. + if (this._heldKeys.has(modifierKey)) { + return; } - }), - Observable.fromEvent(this._datatipElement, 'wheel').subscribe(e => { - // We'll mark this as an 'interaction' only if the scroll target was scrollable. - // This requires going over the ancestors, so only check this once. - // If it comes back as false, we won't bother checking again. - if (!this._checkedScrollable) { - this._isScrollable = isScrollable(this._datatipElement, e); - this._checkedScrollable = true; + this._heldKeys.add(modifierKey); + if (this._datatipState !== DatatipState.HIDDEN) { + this._fetchInResponseToKeyPress(); } - if (this._isScrollable) { - this._interactedWith = true; - e.stopPropagation(); + } else { + this._hideOrCancel(); + } + }), + _rxjsBundlesRxMinJs.Observable.fromEvent(this._editorView, 'keyup').subscribe(e => { + const modifierKey = (0, (_getModifierKeys || _load_getModifierKeys()).getModifierKeyFromKeyboardEvent)(e); + if (modifierKey) { + this._heldKeys.delete(modifierKey); + if (this._datatipState !== DatatipState.HIDDEN) { + this._fetchInResponseToKeyPress(); } - }), - Observable.fromEvent(this._datatipElement, 'mousedown').subscribe(() => { + } + }), + _rxjsBundlesRxMinJs.Observable.fromEvent(this._datatipElement, 'wheel').subscribe(e => { + // We'll mark this as an 'interaction' only if the scroll target was scrollable. + // This requires going over the ancestors, so only check this once. + // If it comes back as false, we won't bother checking again. + if (!this._checkedScrollable) { + this._isScrollable = (0, (_isScrollable || _load_isScrollable()).default)(this._datatipElement, e); + this._checkedScrollable = true; + } + if (this._isScrollable) { this._interactedWith = true; - }), - Observable.fromEvent(this._datatipElement, 'mouseenter').subscribe(() => { - this._insideDatatip = true; - this._hideIfOutside(); - }), - Observable.fromEvent(this._datatipElement, 'mouseleave').subscribe(() => { - this._insideDatatip = false; - this._hideIfOutside(); - }), - this._editorView.onDidChangeScrollTop(() => { - this._lastMoveEvent = null; - if (this._datatipState === DatatipState.VISIBLE) { - this._setState(DatatipState.HIDDEN); - } - }), - this._editor.getBuffer().onDidChangeText(() => { - if (this._datatipState === DatatipState.VISIBLE) { - this._setState(DatatipState.HIDDEN); - } - }), - atom.commands.add( - 'atom-text-editor', - 'datatip:toggle', - this._toggleDatatip, - ), - atom.commands.add( - 'atom-text-editor', - 'datatip:copy-to-clipboard', - this._copyDatatipToClipboard, - ), - ); + e.stopPropagation(); + } + }), + _rxjsBundlesRxMinJs.Observable.fromEvent(this._datatipElement, 'mousedown').subscribe(() => { + this._interactedWith = true; + }), + _rxjsBundlesRxMinJs.Observable.fromEvent(this._datatipElement, 'mouseenter').subscribe(() => { + this._insideDatatip = true; + this._hideIfOutside(); + }), + _rxjsBundlesRxMinJs.Observable.fromEvent(this._datatipElement, 'mouseleave').subscribe(() => { + this._insideDatatip = false; + this._hideIfOutside(); + }), + this._editorView.onDidChangeScrollTop(() => { + this._lastMoveEvent = null; + if (this._datatipState === DatatipState.VISIBLE) { + this._setState(DatatipState.HIDDEN); + } + }), + this._editor.getBuffer().onDidChangeText(() => { + if (this._datatipState === DatatipState.VISIBLE) { + this._setState(DatatipState.HIDDEN); + } + }), + atom.commands.add( + 'atom-text-editor', + 'datatip:toggle', + this._toggleDatatip), + + atom.commands.add( + 'atom-text-editor', + 'datatip:copy-to-clipboard', + this._copyDatatipToClipboard)); + + } _fetchInResponseToKeyPress() { @@ -405,52 +405,52 @@ class DatatipManagerForEditor { this._startFetching(() => this._editor.getCursorBufferPosition()); } else { this._startFetching(() => - getBufferPosition(this._editor, this._editorView, this._lastMoveEvent), - ); + getBufferPosition(this._editor, this._editorView, this._lastMoveEvent)); + } } - _setStartFetchingDebounce(): void { - this._startFetchingDebounce = debounce( - () => { - this._startFetching(() => - getBufferPosition( - this._editor, - this._editorView, - this._lastMoveEvent, - ), - ); - }, - ensurePositiveNumber( - (featureConfig.get('atom-ide-datatip.datatipDebounceDelay'): any), - DEFAULT_DATATIP_DEBOUNCE_DELAY, - ), - /* immediate */ false, - ); + _setStartFetchingDebounce() { + this._startFetchingDebounce = (0, (_debounce || _load_debounce()).default)( + () => { + this._startFetching(() => + getBufferPosition( + this._editor, + this._editorView, + this._lastMoveEvent)); + + + }, + ensurePositiveNumber( + (_featureConfig || _load_featureConfig()).default.get('atom-ide-datatip.datatipDebounceDelay'), + DEFAULT_DATATIP_DEBOUNCE_DELAY), + + /* immediate */false); + } - _setHideIfOutsideDebounce(): void { - this._hideIfOutsideDebounce = debounce( - () => { - this._hideIfOutsideImmediate(); - }, - ensurePositiveNumber( - (featureConfig.get( - 'atom-ide-datatip.datatipInteractedWithDebounceDelay', - ): any), - DEFAULT_DATATIP_INTERACTED_DEBOUNCE_DELAY, - ), - /* immediate */ false, - ); + _setHideIfOutsideDebounce() { + this._hideIfOutsideDebounce = (0, (_debounce || _load_debounce()).default)( + () => { + this._hideIfOutsideImmediate(); + }, + ensurePositiveNumber( + (_featureConfig || _load_featureConfig()).default.get( + 'atom-ide-datatip.datatipInteractedWithDebounceDelay'), + + DEFAULT_DATATIP_INTERACTED_DEBOUNCE_DELAY), + + /* immediate */false); + } - dispose(): void { + dispose() { this._setState(DatatipState.HIDDEN); this._subscriptions.dispose(); this._datatipElement.remove(); } - _setState(newState: State): void { + _setState(newState) { const oldState = this._datatipState; this._datatipState = newState; @@ -462,162 +462,162 @@ class DatatipManagerForEditor { } } - async _startFetching(getPosition: () => ?atom$Point): Promise { - const position = getPosition(); - if (!position) { - return; - } + _startFetching(getPosition) {var _this = this;return (0, _asyncToGenerator.default)(function* () { + const position = getPosition(); + if (!position) { + return; + } - const data = await this._fetchAndRender(position); - if (data == null) { - this._setState(DatatipState.HIDDEN); - return; - } - if (this._datatipState !== DatatipState.FETCHING) { - this._setState(DatatipState.HIDDEN); - } + const data = yield _this._fetchAndRender(position); + if (data == null) { + _this._setState(DatatipState.HIDDEN); + return; + } + if (_this._datatipState !== DatatipState.FETCHING) { + _this._setState(DatatipState.HIDDEN); + } - if ( - this._blacklistedPosition && + if ( + _this._blacklistedPosition && data.range && - data.range.containsPoint(this._blacklistedPosition) - ) { - this._setState(DatatipState.HIDDEN); - return; - } + data.range.containsPoint(_this._blacklistedPosition)) + { + _this._setState(DatatipState.HIDDEN); + return; + } - const currentPosition = getPosition(); - if ( + const currentPosition = getPosition(); + if ( !currentPosition || !data.range || - !data.range.containsPoint(currentPosition) - ) { - this._setState(DatatipState.HIDDEN); - return; - } + !data.range.containsPoint(currentPosition)) + { + _this._setState(DatatipState.HIDDEN); + return; + } - if (this._isHoveringOverPinnedTip()) { - this._setState(DatatipState.HIDDEN); - return; - } + if (_this._isHoveringOverPinnedTip()) { + _this._setState(DatatipState.HIDDEN); + return; + } - this._setState(DatatipState.VISIBLE); - this._interactedWith = false; - this._checkedScrollable = false; - this._range = data.range; + _this._setState(DatatipState.VISIBLE); + _this._interactedWith = false; + _this._checkedScrollable = false; + _this._range = data.range; - if (this._markerDisposable) { - this._markerDisposable.dispose(); - } - this._markerDisposable = mountDatatipWithMarker( - this._editor, - this._datatipElement, + if (_this._markerDisposable) { + _this._markerDisposable.dispose(); + } + _this._markerDisposable = mountDatatipWithMarker( + _this._editor, + _this._datatipElement, data.range, data.renderedProviders, - currentPosition, - ); - } + currentPosition);})(); - async _fetch(position: atom$Point): Promise> { - this._setState(DatatipState.FETCHING); + } - let results: Promise>; - if ( - this._lastPosition != null && - position.isEqual(this._lastPosition) && - this._lastResultsPromise != null - ) { - results = this._lastResultsPromise; - } else { - this._lastResultsPromise = getDatatipResults( - this._datatipProviders, - this._editor, + _fetch(position) {var _this2 = this;return (0, _asyncToGenerator.default)(function* () { + _this2._setState(DatatipState.FETCHING); + + let results; + if ( + _this2._lastPosition != null && + position.isEqual(_this2._lastPosition) && + _this2._lastResultsPromise != null) + { + results = _this2._lastResultsPromise; + } else { + _this2._lastResultsPromise = getDatatipResults( + _this2._datatipProviders, + _this2._editor, position, - provider => provider.datatip(this._editor, position), - ); - results = this._lastResultsPromise; - this._lastPosition = position; - } + function (provider) {return provider.datatip(_this2._editor, position);}); + + results = _this2._lastResultsPromise; + _this2._lastPosition = position; + } + + return (yield results).concat(( + yield getDatatipResults( + _this2._modifierDatatipProviders, + _this2._editor, + position, + function (provider) {return ( + provider.modifierDatatip(_this2._editor, position, _this2._heldKeys));})));})(); + - return (await results).concat( - await getDatatipResults( - this._modifierDatatipProviders, - this._editor, - position, - provider => - provider.modifierDatatip(this._editor, position, this._heldKeys), - ), - ); } - async _fetchAndRender( - position: atom$Point, - ): Promise, - }> { - const datatipsAndProviders = await this._fetch(position); - if (datatipsAndProviders.length === 0) { - return null; - } + _fetchAndRender( + position) + + + + {var _this3 = this;return (0, _asyncToGenerator.default)(function* () { + const datatipsAndProviders = yield _this3._fetch(position); + if (datatipsAndProviders.length === 0) { + return null; + } + + const range = datatipsAndProviders[0].datatip.range; + (_analytics || _load_analytics()).default.track('datatip-popup', { + scope: _this3._editor.getGrammar().scopeName, + providerName: getProviderName(datatipsAndProviders[0].provider), + rangeStartRow: String(range.start.row), + rangeStartColumn: String(range.start.column), + rangeEndRow: String(range.end.row), + rangeEndColumn: String(range.end.column) }); + + + const renderedProviders = + _react.createElement('div', null, + datatipsAndProviders.map(function ({ datatip, provider }) {return ( + _react.createElement(PinnableDatatip, { + datatip: datatip, + editor: _this3._editor, + key: getProviderName(provider), + onPinClick: _this3._handlePinClicked }));})); + + - const range = datatipsAndProviders[0].datatip.range; - analytics.track('datatip-popup', { - scope: this._editor.getGrammar().scopeName, - providerName: getProviderName(datatipsAndProviders[0].provider), - rangeStartRow: String(range.start.row), - rangeStartColumn: String(range.start.column), - rangeEndRow: String(range.end.row), - rangeEndColumn: String(range.end.column), - }); - const renderedProviders = ( -
- {datatipsAndProviders.map(({datatip, provider}) => ( - - ))} -
- ); - - return { - range, - renderedProviders, - }; + + return { + range, + renderedProviders };})(); + } - _isHoveringOverPinnedTip(): boolean { + _isHoveringOverPinnedTip() { const pinnedDataTips = Array.from(this._pinnedDatatips.values()); const hoveringTips = pinnedDataTips.filter(dt => dt.isHovering()); return hoveringTips != null && hoveringTips.length > 0; } - _hideDatatip(): void { + _hideDatatip() { this._lastHiddenTime = performance.now(); if (this._markerDisposable) { this._markerDisposable.dispose(); this._markerDisposable = null; } this._range = null; - ReactDOM.unmountComponentAtNode(this._datatipElement); + _reactDom.default.unmountComponentAtNode(this._datatipElement); this._datatipElement.style.display = 'none'; } - _hideOrCancel(): void { + _hideOrCancel() { if ( - this._datatipState === DatatipState.HIDDEN || - this._datatipState === DatatipState.FETCHING - ) { + this._datatipState === DatatipState.HIDDEN || + this._datatipState === DatatipState.FETCHING) + { if (this._blacklistedPosition == null) { this._blacklistedPosition = getBufferPosition( - this._editor, - this._editorView, - this._lastMoveEvent, - ); + this._editor, + this._editorView, + this._lastMoveEvent); + } return; } @@ -625,7 +625,7 @@ class DatatipManagerForEditor { this._setState(DatatipState.HIDDEN); } - _hideIfOutside(): void { + _hideIfOutside() { if (this._datatipState !== DatatipState.VISIBLE) { return; } @@ -637,7 +637,7 @@ class DatatipManagerForEditor { } } - _hideIfOutsideImmediate(): void { + _hideIfOutsideImmediate() { if (this._datatipState !== DatatipState.VISIBLE) { return; } @@ -651,15 +651,15 @@ class DatatipManagerForEditor { } const currentPosition = getBufferPosition( - this._editor, - this._editorView, - this._lastMoveEvent, - ); + this._editor, + this._editorView, + this._lastMoveEvent); + if ( - currentPosition && - this._range && - this._range.containsPoint(currentPosition) - ) { + currentPosition && + this._range && + this._range.containsPoint(currentPosition)) + { return; } @@ -667,43 +667,43 @@ class DatatipManagerForEditor { } createPinnedDataTip( - datatip: Datatip, - editor: TextEditor, - options?: PinnedDatatipOptions, - ): PinnedDatatip { - const pinnedDatatip = new PinnedDatatip(datatip, editor, { - ...options, + datatip, + editor, + options) + { + const pinnedDatatip = new (_PinnedDatatip || _load_PinnedDatatip()).PinnedDatatip(datatip, editor, Object.assign({}, + options, { onDispose: () => { this._pinnedDatatips.delete(pinnedDatatip); }, hideDataTips: () => { this._hideDatatip(); - }, - }); + } })); + return pinnedDatatip; - } + }}var _initialiseProps = function () {var _this4 = this;this. - _handlePinClicked = (editor: TextEditor, datatip: Datatip) => { - analytics.track('datatip-pinned-open'); - const startTime = performanceNow(); + _handlePinClicked = (editor, datatip) => { + (_analytics || _load_analytics()).default.track('datatip-pinned-open'); + const startTime = (0, (_performanceNow || _load_performanceNow()).default)(); this._setState(DatatipState.HIDDEN); this._pinnedDatatips.add( - new PinnedDatatip(datatip, editor, { - onDispose: pinnedDatatip => { - this._pinnedDatatips.delete(pinnedDatatip); - analytics.track('datatip-pinned-close', { - duration: performanceNow() - startTime, - }); - }, - hideDataTips: () => { - this._hideDatatip(); - }, - position: 'end-of-line', - }), - ); - }; - - _toggleDatatip = (e?: atom$CustomEvent) => { + new (_PinnedDatatip || _load_PinnedDatatip()).PinnedDatatip(datatip, editor, { + onDispose: pinnedDatatip => { + this._pinnedDatatips.delete(pinnedDatatip); + (_analytics || _load_analytics()).default.track('datatip-pinned-close', { + duration: (0, (_performanceNow || _load_performanceNow()).default)() - startTime }); + + }, + hideDataTips: () => { + this._hideDatatip(); + }, + position: 'end-of-line' })); + + + };this. + + _toggleDatatip = e => {var _ref, _ref2; if (atom.workspace.getActiveTextEditor() !== this._editor) { return; } @@ -712,44 +712,44 @@ class DatatipManagerForEditor { // keydown, which is going to be triggered before the key binding which is // evaluated on keyup. // $FlowFixMe (v0.54.1 <) - const maybeEventType = idx(e, _ => _.originalEvent.type); + const maybeEventType = (_ref = e) != null ? (_ref2 = _ref.originalEvent) != null ? _ref2.type : _ref2 : _ref; // Unfortunately, when you do keydown of the shortcut, it's going to // hide it, we need to make sure that when we do keyup, it doesn't show // it up right away. We assume that a keypress is done within 100ms // and don't show it again if it was hidden so soon. const forceShow = - maybeEventType === 'keydown' && - performance.now() - this._lastHiddenTime > 100; + maybeEventType === 'keydown' && + performance.now() - this._lastHiddenTime > 100; const forceHide = maybeEventType === 'keyup'; const forceToggle = - maybeEventType !== 'keydown' && maybeEventType !== 'keyup'; + maybeEventType !== 'keydown' && maybeEventType !== 'keyup'; if ( - // if we have event information, prefer that for determining show/hide - forceShow || - (forceToggle && this._datatipState === DatatipState.HIDDEN) - ) { + // if we have event information, prefer that for determining show/hide + forceShow || + forceToggle && this._datatipState === DatatipState.HIDDEN) + { this._lastFetchedFromCursorPosition = true; this._startFetching(() => this._editor.getCursorScreenPosition()); } else if (forceHide || forceToggle) { this._hideOrCancel(); } - }; + };this. - _copyDatatipToClipboard = async () => { - if (atom.workspace.getActiveTextEditor() !== this._editor) { + _copyDatatipToClipboard = (0, _asyncToGenerator.default)(function* () {var _ref3, _ref4; + if (atom.workspace.getActiveTextEditor() !== _this4._editor) { return; } - const pos = this._editor.getCursorScreenPosition(); + const pos = _this4._editor.getCursorScreenPosition(); if (pos == null) { return; } - const results: Array = await this._fetch(pos); - this._setState(DatatipState.HIDDEN); + const results = yield _this4._fetch(pos); + _this4._setState(DatatipState.HIDDEN); - const tip = idx(results, _ => _[0].datatip); + const tip = (_ref3 = results) != null ? (_ref4 = _ref3[0]) != null ? _ref4.datatip : _ref4 : _ref3; if (tip == null || tip.markedStrings == null) { return; } @@ -759,76 +759,75 @@ class DatatipManagerForEditor { return; } - const value = markedStrings.map(string => string.value).join(); + const value = markedStrings.map(function (string) {return string.value;}).join(); if (value === '') { return; } atom.clipboard.write(value); atom.notifications.addInfo( - `Copied data tip to clipboard: \`\`\`${value}\`\`\``, - ); - }; -} + `Copied data tip to clipboard: \`\`\`${value}\`\`\``); + + });}; + + +class DatatipManager { + + + -export class DatatipManager { - _datatipProviders: ProviderRegistry; - _modifierDatatipProviders: ProviderRegistry; - _editorManagers: Map; - _subscriptions: UniversalDisposable; constructor() { - this._subscriptions = new UniversalDisposable(); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._editorManagers = new Map(); - this._datatipProviders = new ProviderRegistry(); - this._modifierDatatipProviders = new ProviderRegistry(); + this._datatipProviders = new (_ProviderRegistry || _load_ProviderRegistry()).default(); + this._modifierDatatipProviders = new (_ProviderRegistry || _load_ProviderRegistry()).default(); this._subscriptions.add( - observeTextEditors(editor => { - const manager = new DatatipManagerForEditor( - editor, - this._datatipProviders, - this._modifierDatatipProviders, - ); - this._editorManagers.set(editor, manager); - const disposable = new UniversalDisposable(() => { - manager.dispose(); - this._editorManagers.delete(editor); - }); - this._subscriptions.add(disposable); - editor.onDidDestroy(() => disposable.dispose()); - }), - ); + (0, (_textEditor || _load_textEditor()).observeTextEditors)(editor => { + const manager = new DatatipManagerForEditor( + editor, + this._datatipProviders, + this._modifierDatatipProviders); + + this._editorManagers.set(editor, manager); + const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { + manager.dispose(); + this._editorManagers.delete(editor); + }); + this._subscriptions.add(disposable); + editor.onDidDestroy(() => disposable.dispose()); + })); + } - addProvider(provider: DatatipProvider): IDisposable { + addProvider(provider) { return this._datatipProviders.addProvider(provider); } - addModifierProvider(provider: ModifierDatatipProvider): IDisposable { + addModifierProvider(provider) { return this._modifierDatatipProviders.addProvider(provider); } createPinnedDataTip( - datatip: Datatip, - editor: TextEditor, - options?: PinnedDatatipOptions, - ): PinnedDatatip { + datatip, + editor, + options) + { const manager = this._editorManagers.get(editor); if (!manager) { throw new Error( - 'Trying to create a pinned data tip on an editor that has ' + - 'no datatip manager', - ); + 'Trying to create a pinned data tip on an editor that has ' + + 'no datatip manager'); + } return manager.createPinnedDataTip(datatip, editor, options); } - dispose(): void { + dispose() { this._subscriptions.dispose(); this._editorManagers.forEach(manager => { manager.dispose(); }); this._editorManagers = new Map(); - } -} + }}exports.DatatipManager = DatatipManager; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/MarkedStringDatatip.js b/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/MarkedStringDatatip.js index 8d0977f1..8bb8a0f6 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/MarkedStringDatatip.js +++ b/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/MarkedStringDatatip.js @@ -1,47 +1,46 @@ -/** - * 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 - * @format - */ - -import type {MarkedString} from './types'; - -import marked from 'marked'; -import * as React from 'react'; - -import MarkedStringSnippet from './MarkedStringSnippet'; -import createDOMPurify from 'dompurify'; - -const domPurify = createDOMPurify(); - -type Props = { - markedStrings: Array, -}; - -export default class MarkedStringDatatip extends React.PureComponent { - render(): React.Node { - const elements = this.props.markedStrings.map((chunk, i) => { - if (chunk.type === 'markdown') { - return ( -
- ); +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _marked; + + + + + + + + + + + + + +function _load_marked() {return _marked = _interopRequireDefault(require('marked'));} +var _react = _interopRequireWildcard(require('react'));var _MarkedStringSnippet; + +function _load_MarkedStringSnippet() {return _MarkedStringSnippet = _interopRequireDefault(require('./MarkedStringSnippet'));}var _dompurify; +function _load_dompurify() {return _dompurify = _interopRequireDefault(require('dompurify'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +const domPurify = (0, (_dompurify || _load_dompurify()).default)(); /** + * 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. + * + * + * @format + */class MarkedStringDatatip extends _react.PureComponent {render() {const elements = this.props.markedStrings.map((chunk, i) => {if (chunk.type === 'markdown') {return ( + _react.createElement('div', { + className: 'datatip-marked-container', + dangerouslySetInnerHTML: { + __html: domPurify.sanitize((0, (_marked || _load_marked()).default)(chunk.value)) }, + + key: i })); + + } else { - return ; + return _react.createElement((_MarkedStringSnippet || _load_MarkedStringSnippet()).default, Object.assign({ key: i }, chunk)); } }); - return
{elements}
; - } -} + return _react.createElement('div', { className: 'datatip-marked' }, elements); + }}exports.default = MarkedStringDatatip; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/MarkedStringSnippet.js b/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/MarkedStringSnippet.js index 4337d8e3..f0902187 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/MarkedStringSnippet.js +++ b/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/MarkedStringSnippet.js @@ -1,59 +1,58 @@ -/** - * 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 - * @format - */ - -import {TextBuffer} from 'atom'; -import * as React from 'react'; -import {AtomTextEditor} from 'nuclide-commons-ui/AtomTextEditor'; +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); + + + + + + + -// Complex types can end up being super long. Truncate them. -const MAX_LENGTH = 100; -type Props = { - value: string, - grammar: atom$Grammar, -}; -type State = { - isExpanded: boolean, -}; -export default class MarkedStringSnippet extends React.Component { - state = { - isExpanded: false, - }; +var _atom = require('atom'); +var _react = _interopRequireWildcard(require('react'));var _AtomTextEditor; +function _load_AtomTextEditor() {return _AtomTextEditor = require('nuclide-commons-ui/AtomTextEditor');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} - render(): React.Node { - const {grammar, value} = this.props; +// Complex types can end up being super long. Truncate them. +const MAX_LENGTH = 100; /** + * 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. + * + * + * @format + */ +class MarkedStringSnippet extends _react.Component {constructor(...args) {var _temp;return _temp = super(...args), this. + state = { + isExpanded: false }, _temp;} + + + render() { + const { grammar, value } = this.props; const shouldTruncate = value.length > MAX_LENGTH && !this.state.isExpanded; - const buffer = new TextBuffer( - shouldTruncate ? value.substr(0, MAX_LENGTH) + '...' : value, - ); + const buffer = new _atom.TextBuffer( + shouldTruncate ? value.substr(0, MAX_LENGTH) + '...' : value); + return ( -
) => { - this.setState({isExpanded: !this.state.isExpanded}); - e.stopPropagation(); - }}> - -
- ); - } -} + _react.createElement('div', { + className: 'datatip-marked-text-editor-container', + onClick: e => { + this.setState({ isExpanded: !this.state.isExpanded }); + e.stopPropagation(); + } }, + _react.createElement((_AtomTextEditor || _load_AtomTextEditor()).AtomTextEditor, { + className: 'datatip-marked-text-editor', + gutterHidden: true, + readOnly: true, + syncTextContents: false, + autoGrow: true, + grammar: grammar, + textBuffer: buffer }))); + + + + }}exports.default = MarkedStringSnippet; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/PinnedDatatip.js b/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/PinnedDatatip.js index 2d913b34..be2b8ab6 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/PinnedDatatip.js +++ b/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/PinnedDatatip.js @@ -1,94 +1,94 @@ -/** - * 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 - * @format - */ - -import type {Datatip, PinnedDatatipPosition} from './types'; - -type Position = { - x: number, - y: number, -}; - -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import {Observable} from 'rxjs'; -import invariant from 'assert'; -import classnames from 'classnames'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -import {DatatipComponent, DATATIP_ACTIONS} from './DatatipComponent'; -import isScrollable from './isScrollable'; - -const LINE_END_MARGIN = 20; - -let _mouseMove$; -function documentMouseMove$(): Observable { - if (_mouseMove$ == null) { - _mouseMove$ = Observable.fromEvent(document, 'mousemove'); - } - return _mouseMove$; -} +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.PinnedDatatip = undefined;var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + + + + + + + + + + -let _mouseUp$; -function documentMouseUp$(): Observable { + + + + + + + +var _react = _interopRequireWildcard(require('react')); +var _reactDom = _interopRequireDefault(require('react-dom')); +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _classnames; + +function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _DatatipComponent; + +function _load_DatatipComponent() {return _DatatipComponent = require('./DatatipComponent');}var _isScrollable; +function _load_isScrollable() {return _isScrollable = _interopRequireDefault(require('./isScrollable'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +const LINE_END_MARGIN = 20; /** + * 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. + * + * + * @format + */let _mouseMove$;function documentMouseMove$() {if (_mouseMove$ == null) {_mouseMove$ = _rxjsBundlesRxMinJs.Observable.fromEvent(document, 'mousemove');}return _mouseMove$;}let _mouseUp$; +function documentMouseUp$() { if (_mouseUp$ == null) { - _mouseUp$ = Observable.fromEvent(document, 'mouseup'); + _mouseUp$ = _rxjsBundlesRxMinJs.Observable.fromEvent(document, 'mouseup'); } return _mouseUp$; } -export type PinnedDatatipParams = { - onDispose: (pinnedDatatip: PinnedDatatip) => void, - hideDataTips: () => void, - // Defaults to 'end-of-line'. - position?: PinnedDatatipPosition, - // Defaults to true. - showRangeHighlight?: boolean, -}; - -export class PinnedDatatip { - _boundDispose: Function; - _boundHandleMouseDown: Function; - _boundHandleMouseEnter: Function; - _boundHandleMouseLeave: Function; - _boundHandleCapturedClick: Function; - _mouseUpTimeout: ?TimeoutID; - _hostElement: HTMLElement; - _marker: ?atom$Marker; - _rangeDecoration: ?atom$Decoration; - _mouseSubscription: ?rxjs$ISubscription; - _subscriptions: UniversalDisposable; - _datatip: Datatip; - _editor: TextEditor; - _hostElement: HTMLElement; - _boundDispose: Function; - _dragOrigin: ?Position; - _isDragging: boolean; - _offset: Position; - _isHovering: boolean; - _checkedScrollable: boolean; - _isScrollable: boolean; - _hideDataTips: () => void; - _position: PinnedDatatipPosition; - _showRangeHighlight: boolean; + + + + + + + + + +class PinnedDatatip { + + + + + + + + + + + + + + + + + + + + + + + + constructor( - datatip: Datatip, - editor: TextEditor, - params: PinnedDatatipParams, - ) { - this._subscriptions = new UniversalDisposable(); + datatip, + editor, + params) + { + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._subscriptions.add( - new UniversalDisposable(() => params.onDispose(this)), - ); + new (_UniversalDisposable || _load_UniversalDisposable()).default(() => params.onDispose(this))); + this._datatip = datatip; this._editor = editor; this._marker = null; @@ -104,74 +104,74 @@ export class PinnedDatatip { this._isScrollable = false; this._subscriptions.add( - Observable.fromEvent(this._hostElement, 'wheel').subscribe(e => { - if (!this._checkedScrollable) { - this._isScrollable = isScrollable(this._hostElement, e); - this._checkedScrollable = true; - } - if (this._isScrollable) { - e.stopPropagation(); - } - }), - ); + _rxjsBundlesRxMinJs.Observable.fromEvent(this._hostElement, 'wheel').subscribe(e => { + if (!this._checkedScrollable) { + this._isScrollable = (0, (_isScrollable || _load_isScrollable()).default)(this._hostElement, e); + this._checkedScrollable = true; + } + if (this._isScrollable) { + e.stopPropagation(); + } + })); + this._hostElement.addEventListener( - 'mouseenter', - this._boundHandleMouseEnter, - ); + 'mouseenter', + this._boundHandleMouseEnter); + this._hostElement.addEventListener( - 'mouseleave', - this._boundHandleMouseLeave, - ); + 'mouseleave', + this._boundHandleMouseLeave); + this._subscriptions.add( - new UniversalDisposable(() => { - this._hostElement.removeEventListener( - 'mouseenter', - this._boundHandleMouseEnter, - ); - this._hostElement.removeEventListener( - 'mouseleave', - this._boundHandleMouseLeave, - ); - }), - ); + new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { + this._hostElement.removeEventListener( + 'mouseenter', + this._boundHandleMouseEnter); + + this._hostElement.removeEventListener( + 'mouseleave', + this._boundHandleMouseLeave); + + })); + this._mouseUpTimeout = null; - this._offset = {x: 0, y: 0}; + this._offset = { x: 0, y: 0 }; this._isDragging = false; this._dragOrigin = null; this._isHovering = false; this._hideDataTips = params.hideDataTips; this._position = params.position == null ? 'end-of-line' : params.position; this._showRangeHighlight = - params.showRangeHighlight == null ? true : params.showRangeHighlight; + params.showRangeHighlight == null ? true : params.showRangeHighlight; this.render(); } - handleMouseEnter(event: MouseEvent): void { + handleMouseEnter(event) { this._isHovering = true; this._hideDataTips(); } - handleMouseLeave(event: MouseEvent): void { + handleMouseLeave(event) { this._isHovering = false; } - isHovering(): boolean { + isHovering() { return this._isHovering; } - handleGlobalMouseMove(event: Event): void { - const evt: MouseEvent = (event: any); - const {_dragOrigin} = this; - invariant(_dragOrigin); + handleGlobalMouseMove(event) { + const evt = event; + const { _dragOrigin } = this;if (! + _dragOrigin) {throw new Error('Invariant violation: "_dragOrigin"');} this._isDragging = true; this._offset = { x: evt.clientX - _dragOrigin.x, - y: evt.clientY - _dragOrigin.y, - }; + y: evt.clientY - _dragOrigin.y }; + this.render(); } - handleGlobalMouseUp(): void { + handleGlobalMouseUp() { // If the datatip was moved, push the effects of mouseUp to the next tick, // in order to allow cancellation of captured events (e.g. clicks on child components). this._mouseUpTimeout = setTimeout(() => { @@ -183,34 +183,34 @@ export class PinnedDatatip { }, 0); } - _ensureMouseSubscriptionDisposed(): void { + _ensureMouseSubscriptionDisposed() { if (this._mouseSubscription != null) { this._mouseSubscription.unsubscribe(); this._mouseSubscription = null; } } - handleMouseDown(event: Event): void { - const evt: MouseEvent = (event: any); + handleMouseDown(event) { + const evt = event; this._dragOrigin = { x: evt.clientX - this._offset.x, - y: evt.clientY - this._offset.y, - }; + y: evt.clientY - this._offset.y }; + this._ensureMouseSubscriptionDisposed(); - this._mouseSubscription = documentMouseMove$() - .takeUntil(documentMouseUp$()) - .subscribe( - (e: MouseEvent) => { - this.handleGlobalMouseMove(e); - }, - (error: any) => {}, - () => { - this.handleGlobalMouseUp(); - }, - ); + this._mouseSubscription = documentMouseMove$(). + takeUntil(documentMouseUp$()). + subscribe( + e => { + this.handleGlobalMouseMove(e); + }, + error => {}, + () => { + this.handleGlobalMouseUp(); + }); + } - handleCapturedClick(event: SyntheticEvent<>): void { + handleCapturedClick(event) { if (this._isDragging) { event.stopPropagation(); } else { @@ -220,94 +220,94 @@ export class PinnedDatatip { } // Update the position of the pinned datatip. - _updateHostElementPosition(): void { - const {_editor, _datatip, _hostElement, _offset, _position} = this; - const {range} = _datatip; + _updateHostElementPosition() { + const { _editor, _datatip, _hostElement, _offset, _position } = this; + const { range } = _datatip; _hostElement.style.display = 'block'; switch (_position) { case 'end-of-line': const charWidth = _editor.getDefaultCharWidth(); - const lineLength = _editor.getBuffer().getLines()[range.start.row] - .length; + const lineLength = _editor.getBuffer().getLines()[range.start.row]. + length; _hostElement.style.top = - -_editor.getLineHeightInPixels() + _offset.y + 'px'; + -_editor.getLineHeightInPixels() + _offset.y + 'px'; _hostElement.style.left = - (lineLength - range.end.column) * charWidth + - LINE_END_MARGIN + - _offset.x + - 'px'; + (lineLength - range.end.column) * charWidth + + LINE_END_MARGIN + + _offset.x + + 'px'; break; case 'above-range': _hostElement.style.bottom = - _editor.getLineHeightInPixels() + - _hostElement.clientHeight - - _offset.y + - 'px'; + _editor.getLineHeightInPixels() + + _hostElement.clientHeight - + _offset.y + + 'px'; _hostElement.style.left = _offset.x + 'px'; break; default: - (_position: empty); - throw Error(`Unexpected PinnedDatatip position: ${this._position}`); - } + _position; + throw Error(`Unexpected PinnedDatatip position: ${this._position}`);} + } - async render(): Promise { - const {_editor, _datatip, _hostElement, _isDragging, _isHovering} = this; + render() {var _this = this;return (0, _asyncToGenerator.default)(function* () { + const { _editor, _datatip, _hostElement, _isDragging, _isHovering } = _this; - let rangeClassname = 'datatip-highlight-region'; - if (_isHovering) { - rangeClassname += ' datatip-highlight-region-active'; - } + let rangeClassname = 'datatip-highlight-region'; + if (_isHovering) { + rangeClassname += ' datatip-highlight-region-active'; + } + + if (_this._marker == null) { + const marker = _editor.markBufferRange(_datatip.range, { + invalidate: 'never' }); + + _this._marker = marker; + _editor.decorateMarker(marker, { + type: 'overlay', + position: 'head', + item: _this._hostElement, + // above-range datatips currently assume that the overlay is below. + avoidOverflow: _this._position !== 'above-range' }); - if (this._marker == null) { - const marker: atom$Marker = _editor.markBufferRange(_datatip.range, { - invalidate: 'never', - }); - this._marker = marker; - _editor.decorateMarker(marker, { - type: 'overlay', - position: 'head', - item: this._hostElement, - // above-range datatips currently assume that the overlay is below. - avoidOverflow: this._position !== 'above-range', - }); - if (this._showRangeHighlight) { - this._rangeDecoration = _editor.decorateMarker(marker, { + if (_this._showRangeHighlight) { + _this._rangeDecoration = _editor.decorateMarker(marker, { + type: 'highlight', + class: rangeClassname }); + + } + yield _editor.getElement().getNextUpdatePromise(); + // Guard against disposals during the await. + if (marker.isDestroyed() || _editor.isDestroyed()) { + return; + } + } else if (_this._rangeDecoration != null) { + _this._rangeDecoration.setProperties({ type: 'highlight', - class: rangeClassname, - }); - } - await _editor.getElement().getNextUpdatePromise(); - // Guard against disposals during the await. - if (marker.isDestroyed() || _editor.isDestroyed()) { - return; + class: rangeClassname }); + } - } else if (this._rangeDecoration != null) { - this._rangeDecoration.setProperties({ - type: 'highlight', - class: rangeClassname, - }); - } - ReactDOM.render( - , - _hostElement, - ); - this._updateHostElementPosition(); + _reactDom.default.render( + _react.createElement((_DatatipComponent || _load_DatatipComponent()).DatatipComponent, { + action: (_DatatipComponent || _load_DatatipComponent()).DATATIP_ACTIONS.CLOSE, + actionTitle: 'Close this datatip', + className: (0, (_classnames || _load_classnames()).default)( + _isDragging ? 'datatip-dragging' : '', + 'datatip-pinned'), + + datatip: _datatip, + onActionClick: _this._boundDispose, + onMouseDown: _this._boundHandleMouseDown, + onClickCapture: _this._boundHandleCapturedClick }), + + _hostElement); + + _this._updateHostElementPosition();})(); } - dispose(): void { + dispose() { if (this._mouseUpTimeout != null) { clearTimeout(this._mouseUpTimeout); } @@ -317,8 +317,7 @@ export class PinnedDatatip { if (this._mouseSubscription != null) { this._mouseSubscription.unsubscribe(); } - ReactDOM.unmountComponentAtNode(this._hostElement); + _reactDom.default.unmountComponentAtNode(this._hostElement); this._hostElement.remove(); this._subscriptions.dispose(); - } -} + }}exports.PinnedDatatip = PinnedDatatip; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/getModifierKeys.js b/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/getModifierKeys.js index 0ec9fd8d..3ba27223 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/getModifierKeys.js +++ b/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/getModifierKeys.js @@ -1,45 +1,51 @@ -/** - * 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 - * @format - */ - -import type {ModifierKey} from './types'; -import {ModifierKeys} from './types'; - -const KEYNAME_TO_PROPERTY = { - Meta: ModifierKeys.META, - Shift: ModifierKeys.SHIFT, - Alt: ModifierKeys.ALT, - Control: ModifierKeys.CTRL, -}; - -export function getModifierKeysFromMouseEvent(e: MouseEvent): Set { - const keys: Set = new Set(); - if (e.metaKey) { - keys.add(ModifierKeys.META); - } - if (e.shiftKey) { - keys.add(ModifierKeys.SHIFT); - } - if (e.altKey) { - keys.add(ModifierKeys.ALT); - } - if (e.ctrlKey) { - keys.add(ModifierKeys.CTRL); - } - - return keys; -} - -export function getModifierKeyFromKeyboardEvent( - e: KeyboardEvent, -): ?ModifierKey { - return KEYNAME_TO_PROPERTY[e.key]; -} +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + + + + + + + + + +getModifierKeysFromMouseEvent = getModifierKeysFromMouseEvent;exports. + + + + + + + + + + + + + + + + + +getModifierKeyFromKeyboardEvent = getModifierKeyFromKeyboardEvent;var _types;function _load_types() {return _types = require('./types');} /** + * 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. + * + * + * @format + */const KEYNAME_TO_PROPERTY = { Meta: (_types || _load_types()).ModifierKeys.META, Shift: (_types || _load_types()).ModifierKeys.SHIFT, Alt: (_types || _load_types()).ModifierKeys.ALT, Control: (_types || _load_types()).ModifierKeys.CTRL };function getModifierKeysFromMouseEvent(e) {const keys = new Set();if (e.metaKey) {keys.add((_types || _load_types()).ModifierKeys.META);}if (e.shiftKey) {keys.add((_types || _load_types()).ModifierKeys.SHIFT);}if (e.altKey) {keys.add((_types || _load_types()).ModifierKeys.ALT);}if (e.ctrlKey) {keys.add((_types || _load_types()).ModifierKeys.CTRL);}return keys;}function getModifierKeyFromKeyboardEvent(e) {return KEYNAME_TO_PROPERTY[e.key];} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/isScrollable.js b/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/isScrollable.js index 2e3fcf0a..588b7b46 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/isScrollable.js +++ b/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/isScrollable.js @@ -1,28 +1,28 @@ -/** - * 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 - * @format - */ - -export default function isScrollable( - element: Element, - wheelEvent: WheelEvent, -): boolean { - let node: ?Element = ((wheelEvent.target: any): Element); - while (node != null && node !== element) { - if ( - node.scrollHeight > node.clientHeight || - node.scrollWidth > node.clientWidth - ) { - return true; +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = + + + + + + + + + + + +isScrollable; /** + * 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. + * + * + * @format + */function isScrollable(element, wheelEvent) {let node = wheelEvent.target;while (node != null && node !== element) {if (node.scrollHeight > node.clientHeight || node.scrollWidth > node.clientWidth) {return true; } - node = ((node.parentNode: any): Element); + node = node.parentNode; } return false; -} +} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/main.js b/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/main.js index 3b4b9434..1c65fba1 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/main.js +++ b/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/main.js @@ -1,34 +1,41 @@ -/** - * 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 - * @format - */ - -import type {DatatipService} from './types'; - -import createPackage from 'nuclide-commons-atom/createPackage'; -import {DatatipManager} from './DatatipManager'; +'use strict';var _createPackage; + + + + + + + + + + + + + +function _load_createPackage() {return _createPackage = _interopRequireDefault(require('nuclide-commons-atom/createPackage'));}var _DatatipManager; +function _load_DatatipManager() {return _DatatipManager = require('./DatatipManager');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} class Activation { - _datatipManager: DatatipManager; + constructor() { - this._datatipManager = new DatatipManager(); + this._datatipManager = new (_DatatipManager || _load_DatatipManager()).DatatipManager(); } - provideDatatipService(): DatatipService { + provideDatatipService() { return this._datatipManager; } dispose() { this._datatipManager.dispose(); - } -} - -createPackage(module.exports, Activation); + }} /** + * 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. + * + * + * @format + */(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/types.js b/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/types.js index aad7d4f8..b7fa5993 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/types.js +++ b/modules/atom-ide-ui/pkg/atom-ide-datatip/lib/types.js @@ -1,93 +1,90 @@ -/** - * 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 - * @format - */ +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); /** + * 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. + * + * + * @format + */ /** - * Consumers of the "datatip" service get an instance of this service. - * You can register providers (which will be triggered on mouseover) or manually - * create pinned datatips on-demand. - */ -export type DatatipService = { - addProvider(provider: DatatipProvider): IDisposable, - addModifierProvider(provider: ModifierDatatipProvider): IDisposable, - createPinnedDataTip( - datatip: Datatip, - editor: TextEditor, - options?: PinnedDatatipOptions, - ): IDisposable, -}; - -export type PinnedDatatipOptions = {| - // Defaults to 'end-of-line'. - position?: PinnedDatatipPosition, - // Defaults to true. - showRangeHighlight?: boolean, -|}; - -export type PinnedDatatipPosition = 'end-of-line' | 'above-range'; - -export type DatatipProvider = { - priority: number, - grammarScopes?: Array, - // A unique name for the provider to be used for analytics. - // It is recommended that it be the name of the provider's package. - providerName: string, - datatip( - editor: atom$TextEditor, - bufferPosition: atom$Point, - ): Promise, -}; - -export type ModifierDatatipProvider = { - priority: number, - grammarScopes?: Array, - providerName: string, - modifierDatatip( - editor: atom$TextEditor, - bufferPosition: atom$Point, - heldKeys: Set, - ): Promise, -}; - -export type AnyDatatipProvider = DatatipProvider | ModifierDatatipProvider; - -export type Datatip = - | {| - component: React$ComponentType, - range: atom$Range, - pinnable?: boolean, - |} - | {| - markedStrings: Array, - range: atom$Range, - pinnable?: boolean, - |}; - -// Borrowed from the LSP API. -export type MarkedString = - | { - type: 'markdown', - value: string, - } - | { - type: 'snippet', - grammar: atom$Grammar, - value: string, - }; - -export const ModifierKeys = Object.freeze({ + * Consumers of the "datatip" service get an instance of this service. + * You can register providers (which will be triggered on mouseover) or manually + * create pinned datatips on-demand. + */ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +const ModifierKeys = exports.ModifierKeys = Object.freeze({ META: 'metaKey', SHIFT: 'shiftKey', ALT: 'altKey', - CTRL: 'ctrlKey', -}); - -export type ModifierKey = 'metaKey' | 'shiftKey' | 'altKey' | 'ctrlKey'; + CTRL: 'ctrlKey' }); // Borrowed from the LSP API. \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/AtomServiceContainer.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/AtomServiceContainer.js index 4cae6107..36c81791 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/AtomServiceContainer.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/AtomServiceContainer.js @@ -1,130 +1,140 @@ -/** - * 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 - * @format - */ - -import type { - DatatipService, - ConsoleService, - RegisterExecutorFunction, - TerminalApi, -} from 'atom-ide-ui'; -import type { - DebuggerConfigurationProvider, - IProcessConfig, -} from 'nuclide-debugger-common'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -type raiseNativeNotificationFunc = ?( - title: string, - body: string, - timeout: number, - raiseIfAtomHasFocus: boolean, -) => ?IDisposable; - -let _raiseNativeNotification: ?raiseNativeNotificationFunc = null; -let _registerExecutor: ?RegisterExecutorFunction = null; -let _datatipService: ?DatatipService = null; -let _createConsole: ?ConsoleService = null; -let _terminalService: ?TerminalApi = null; -let _rpcService: ?nuclide$RpcService = null; -let _configurationProviders: Array = []; - -export function setConsoleService(createConsole: ConsoleService): IDisposable { - _createConsole = createConsole; - return new UniversalDisposable(() => { - _createConsole = null; - }); -} - -export function getConsoleService(): ?ConsoleService { - return _createConsole; -} - -export function setConsoleRegisterExecutor( - registerExecutor: RegisterExecutorFunction, -): IDisposable { - _registerExecutor = registerExecutor; - return new UniversalDisposable(() => { - _registerExecutor = null; - }); -} - -export function getConsoleRegisterExecutor(): ?RegisterExecutorFunction { - return _registerExecutor; -} - -export function setDatatipService(datatipService: DatatipService): IDisposable { - _datatipService = datatipService; - return new UniversalDisposable(() => { - _datatipService = null; - }); -} - -export function getDatatipService(): ?DatatipService { - return _datatipService; -} - -export function setNotificationService( - raiseNativeNotification: raiseNativeNotificationFunc, -): void { - _raiseNativeNotification = raiseNativeNotification; -} - -export function getNotificationService(): ?raiseNativeNotificationFunc { - return _raiseNativeNotification; -} - -export function setTerminalService(terminalService: TerminalApi): IDisposable { - _terminalService = terminalService; - return new UniversalDisposable(() => { - _terminalService = null; - }); -} - -export function getTerminalService(): ?TerminalApi { - return _terminalService; -} - -export function setRpcService(rpcService: nuclide$RpcService): IDisposable { - _rpcService = rpcService; - return new UniversalDisposable(() => { - _rpcService = null; - }); -} - -export function isNuclideEnvironment(): boolean { - return _rpcService != null; -} - -export function addDebugConfigurationProvider( - provider: DebuggerConfigurationProvider, -): IDisposable { - _configurationProviders.push(provider); - return new UniversalDisposable(() => { - _configurationProviders = _configurationProviders.filter( - p => p !== provider, - ); - }); -} - -export async function resolveDebugConfiguration( - configuration: IProcessConfig, -): Promise { - let resolvedConfiguration = configuration; - for (const provider of _configurationProviders) { - // eslint-disable-next-line no-await-in-loop - resolvedConfiguration = await provider.resolveConfiguration( - resolvedConfiguration, - ); - } - return resolvedConfiguration; -} +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.resolveDebugConfiguration = undefined;var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));let resolveDebugConfiguration = exports.resolveDebugConfiguration = (() => {var _ref = (0, _asyncToGenerator.default)( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + function* ( + configuration) + { + let resolvedConfiguration = configuration; + for (const provider of _configurationProviders) { + // eslint-disable-next-line no-await-in-loop + resolvedConfiguration = yield provider.resolveConfiguration( + resolvedConfiguration); + + } + return resolvedConfiguration; + });return function resolveDebugConfiguration(_x) {return _ref.apply(this, arguments);};})();exports.setConsoleService = setConsoleService;exports.getConsoleService = getConsoleService;exports.setConsoleRegisterExecutor = setConsoleRegisterExecutor;exports.getConsoleRegisterExecutor = getConsoleRegisterExecutor;exports.setDatatipService = setDatatipService;exports.getDatatipService = getDatatipService;exports.setNotificationService = setNotificationService;exports.getNotificationService = getNotificationService;exports.setTerminalService = setTerminalService;exports.getTerminalService = getTerminalService;exports.setRpcService = setRpcService;exports.isNuclideEnvironment = isNuclideEnvironment;exports.addDebugConfigurationProvider = addDebugConfigurationProvider;var _UniversalDisposable;function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}let _raiseNativeNotification = null; /** + * 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. + * + * + * @format + */let _registerExecutor = null;let _datatipService = null;let _createConsole = null;let _terminalService = null;let _rpcService = null;let _configurationProviders = [];function setConsoleService(createConsole) {_createConsole = createConsole;return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => {_createConsole = null;});}function getConsoleService() {return _createConsole;}function setConsoleRegisterExecutor(registerExecutor) {_registerExecutor = registerExecutor;return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => {_registerExecutor = null;});}function getConsoleRegisterExecutor() {return _registerExecutor;}function setDatatipService(datatipService) {_datatipService = datatipService;return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => {_datatipService = null;});}function getDatatipService() {return _datatipService;}function setNotificationService(raiseNativeNotification) {_raiseNativeNotification = raiseNativeNotification;}function getNotificationService() {return _raiseNativeNotification;}function setTerminalService(terminalService) {_terminalService = terminalService;return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => {_terminalService = null;});}function getTerminalService() {return _terminalService;}function setRpcService(rpcService) {_rpcService = rpcService;return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => {_rpcService = null;});}function isNuclideEnvironment() {return _rpcService != null;}function addDebugConfigurationProvider(provider) {_configurationProviders.push(provider);return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => {_configurationProviders = _configurationProviders.filter(p => p !== provider);});} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/BreakpointDisplayController.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/BreakpointDisplayController.js index 1cb9550e..22ea6352 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/BreakpointDisplayController.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/BreakpointDisplayController.js @@ -1,68 +1,68 @@ -/** - * 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 - * @format - */ - -import type {IBreakpoint, IDebugService} from './types'; - -import invariant from 'assert'; -import {bufferPositionForMouseEvent} from 'nuclide-commons-atom/mouse-to-position'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import {fastDebounce} from 'nuclide-commons/observable'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {showMenuForEvent} from 'nuclide-commons-atom/ContextMenu'; -import classnames from 'classnames'; -import {DebuggerMode} from './constants'; -import featureConfig from 'nuclide-commons-atom/feature-config'; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _mouseToPosition; + + + + + + + + + + + + + + +function _load_mouseToPosition() {return _mouseToPosition = require('nuclide-commons-atom/mouse-to-position');}var _event; +function _load_event() {return _event = require('nuclide-commons/event');}var _observable; +function _load_observable() {return _observable = require('nuclide-commons/observable');}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _ContextMenu; +function _load_ContextMenu() {return _ContextMenu = require('nuclide-commons-atom/ContextMenu');}var _classnames; +function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));}var _constants; +function _load_constants() {return _constants = require('./constants');}var _featureConfig; +function _load_featureConfig() {return _featureConfig = _interopRequireDefault(require('nuclide-commons-atom/feature-config'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + + + + + + + + + + + + + + + + -/** - * A single delegate which handles events from the object. - * - * This is simpler than registering handlers using emitter events directly, as - * there's less messy bookkeeping regarding lifetimes of the unregister - * Disposable objects. - */ -type BreakpointDisplayControllerDelegate = { - +handleTextEditorDestroyed: (controller: BreakpointDisplayController) => void, -}; - -type BreakpointMarkerProperties = {| - enabled: boolean, - resolved: boolean, - conditional: boolean, -|}; /** - * Handles displaying breakpoints and processing events for a single text - * editor. - */ -export default class BreakpointDisplayController { - _service: IDebugService; - _delegate: BreakpointDisplayControllerDelegate; - _disposables: UniversalDisposable; - _editor: atom$TextEditor; - _gutter: ?atom$Gutter; - _markers: Array; - _markerInfo: Map; - _lastShadowBreakpointMarker: ?atom$Marker; - _boundGlobalMouseMoveHandler: (event: MouseEvent) => void; - _boundCreateContextMenuHandler: (event: MouseEvent) => void; - _debugging: boolean; - - constructor( - delegate: BreakpointDisplayControllerDelegate, - service: IDebugService, - editor: atom$TextEditor, - ) { + * Handles displaying breakpoints and processing events for a single text + * editor. + */ /** + * A single delegate which handles events from the object. + * + * This is simpler than registering handlers using emitter events directly, as + * there's less messy bookkeeping regarding lifetimes of the unregister + * Disposable objects. + */ /** + * 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. + * + * + * @format + */class BreakpointDisplayController {constructor(delegate, service, + editor) + { this._delegate = delegate; - this._disposables = new UniversalDisposable(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._service = service; this._editor = editor; this._markers = []; @@ -70,8 +70,8 @@ export default class BreakpointDisplayController { this._lastShadowBreakpointMarker = null; this._boundGlobalMouseMoveHandler = this._handleGlobalMouseLeave.bind(this); this._boundCreateContextMenuHandler = this._handleCreateContextMenu.bind( - this, - ); + this); + this._debugging = this._isDebugging(); // Configure the gutter. @@ -79,49 +79,49 @@ export default class BreakpointDisplayController { name: 'debugger-breakpoint', visible: false, // Priority is -200 by default and 0 is the line number - priority: -1100, - }); + priority: -1100 }); + const debuggerModel = this._service.getModel(); this._gutter = gutter; this._disposables.add( - gutter.onDidDestroy(this._handleGutterDestroyed.bind(this)), - editor.observeGutters(this._registerGutterMouseHandlers.bind(this)), - observableFromSubscribeFunction( - debuggerModel.onDidChangeBreakpoints.bind(debuggerModel), - ) - // Debounce to account for bulk updates and not block the UI - .let(fastDebounce(10)) - .startWith(null) - .subscribe(this._update.bind(this)), - this._editor.onDidDestroy(this._handleTextEditorDestroyed.bind(this)), - this._registerEditorContextMenuHandler(), - ); + gutter.onDidDestroy(this._handleGutterDestroyed.bind(this)), + editor.observeGutters(this._registerGutterMouseHandlers.bind(this)), + (0, (_event || _load_event()).observableFromSubscribeFunction)( + debuggerModel.onDidChangeBreakpoints.bind(debuggerModel)) + + // Debounce to account for bulk updates and not block the UI + .let((0, (_observable || _load_observable()).fastDebounce)(10)). + startWith(null). + subscribe(this._update.bind(this)), + this._editor.onDidDestroy(this._handleTextEditorDestroyed.bind(this)), + this._registerEditorContextMenuHandler()); + } - _isDebugging(): boolean { - return this._service.getDebuggerMode() !== DebuggerMode.STOPPED; + _isDebugging() { + return this._service.getDebuggerMode() !== (_constants || _load_constants()).DebuggerMode.STOPPED; } - _registerEditorContextMenuHandler(): IDisposable { + _registerEditorContextMenuHandler() { const editorElement = atom.views.getView(this._editor); editorElement.addEventListener( - 'contextmenu', - this._boundCreateContextMenuHandler, - ); - return new UniversalDisposable(() => - editorElement.removeEventListener( - 'contextmenu', - this._boundCreateContextMenuHandler, - ), - ); + 'contextmenu', + this._boundCreateContextMenuHandler); + + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => + editorElement.removeEventListener( + 'contextmenu', + this._boundCreateContextMenuHandler)); + + } - _registerGutterMouseHandlers(gutter: atom$Gutter): void { + _registerGutterMouseHandlers(gutter) { const gutterView = atom.views.getView(gutter); if ( - gutter.name !== 'line-number' && - gutter.name !== 'debugger-breakpoint' - ) { + gutter.name !== 'line-number' && + gutter.name !== 'debugger-breakpoint') + { return; } const boundClickHandler = this._handleGutterClick.bind(this); @@ -134,30 +134,30 @@ export default class BreakpointDisplayController { gutterView.addEventListener('mouseenter', boundMouseEnterHandler); gutterView.addEventListener('mouseleave', boundMouseLeaveHandler); gutterView.addEventListener( - 'contextmenu', - this._boundCreateContextMenuHandler, - ); + 'contextmenu', + this._boundCreateContextMenuHandler); + this._disposables.add( - () => gutterView.removeEventListener('click', boundClickHandler), - () => gutterView.removeEventListener('mousemove', boundMouseMoveHandler), - () => - gutterView.removeEventListener('mouseenter', boundMouseEnterHandler), - () => - gutterView.removeEventListener('mouseleave', boundMouseLeaveHandler), - () => - gutterView.removeEventListener( - 'contextmenu', - this._boundCreateContextMenuHandler, - ), - () => - window.removeEventListener( - 'mousemove', - this._boundGlobalMouseMoveHandler, - ), - ); + () => gutterView.removeEventListener('click', boundClickHandler), + () => gutterView.removeEventListener('mousemove', boundMouseMoveHandler), + () => + gutterView.removeEventListener('mouseenter', boundMouseEnterHandler), + () => + gutterView.removeEventListener('mouseleave', boundMouseLeaveHandler), + () => + gutterView.removeEventListener( + 'contextmenu', + this._boundCreateContextMenuHandler), + + () => + window.removeEventListener( + 'mousemove', + this._boundGlobalMouseMoveHandler)); + + } - _handleCreateContextMenu(event: MouseEvent): void { + _handleCreateContextMenu(event) { if (event.button !== 2 || !this._isDebugging()) { return; } @@ -167,11 +167,11 @@ export default class BreakpointDisplayController { const menuTemplate = atom.contextMenu.templateForEvent(event); const debuggerGroupIndex = menuTemplate.findIndex( - item => item.label === 'Debugger', - ); + item => item.label === 'Debugger'); + const [debuggerGroup] = menuTemplate.splice(debuggerGroupIndex, 1); - menuTemplate.unshift(...debuggerGroup.submenu, {type: 'separator'}); - showMenuForEvent(event, menuTemplate); + menuTemplate.unshift(...debuggerGroup.submenu, { type: 'separator' }); + (0, (_ContextMenu || _load_ContextMenu()).showMenuForEvent)(event, menuTemplate); } dispose() { @@ -182,7 +182,7 @@ export default class BreakpointDisplayController { } } - getEditor(): atom$TextEditor { + getEditor() { return this._editor; } @@ -199,7 +199,7 @@ export default class BreakpointDisplayController { this._gutter = null; } - _needsUpdate(line: number, bp: ?IBreakpoint): boolean { + _needsUpdate(line, bp) { // Checks if an existing marker no longer matches the properties of the breakpoint // it corresponds to. if (bp == null) { @@ -212,28 +212,28 @@ export default class BreakpointDisplayController { } if ( - info.enabled !== bp.enabled || - info.resolved !== bp.verified || - info.conditional !== (bp.condition != null) - ) { + info.enabled !== bp.enabled || + info.resolved !== bp.verified || + info.conditional !== (bp.condition != null)) + { return true; } return false; } - _getLineForBp(bp: IBreakpoint): number { + _getLineForBp(bp) { // Zero-based breakpoints line map (to match UI markers). return ( (bp.endLine != null && !Number.isNaN(bp.endLine) ? bp.endLine : bp.line) - - 1 - ); + 1); + } /** - * Update the display with the current set of breakpoints for this editor. - */ - _update(): void { + * Update the display with the current set of breakpoints for this editor. + */ + _update() { const gutter = this._gutter; if (gutter == null) { return; @@ -248,8 +248,8 @@ export default class BreakpointDisplayController { const allBreakpoints = this._service.getModel().getBreakpoints(); const breakpoints = allBreakpoints.filter(bp => bp.uri === path); const lineMap = new Map( - breakpoints.map(bp => [this._getLineForBp(bp), bp]), - ); + breakpoints.map(bp => [this._getLineForBp(bp), bp])); + // A mutable unhandled lines map. const unhandledLines = new Set(lineMap.keys()); @@ -260,10 +260,10 @@ export default class BreakpointDisplayController { const line = marker.getStartBufferPosition().row; const bp = lineMap.get(line); if ( - debugging === this._debugging && - unhandledLines.has(line) && - !this._needsUpdate(line, bp) - ) { + debugging === this._debugging && + unhandledLines.has(line) && + !this._needsUpdate(line, bp)) + { markersToKeep.push(marker); unhandledLines.delete(line); } else { @@ -289,18 +289,18 @@ export default class BreakpointDisplayController { continue; } const marker = this._createBreakpointMarkerAtLine( - line, - false, // isShadow - breakpoint, - ); + line, + false, // isShadow + breakpoint); + // Remember the properties of the marker at this line so it's easy to tell if it // needs to be updated when the breakpoint properties change. this._markerInfo.set(line, { enabled: breakpoint.enabled, resolved: breakpoint.verified, - conditional: breakpoint.condition != null, - }); + conditional: breakpoint.condition != null }); + marker.onDidChange(this._handleMarkerChange.bind(this, breakpoint)); markersToKeep.push(marker); } @@ -310,12 +310,12 @@ export default class BreakpointDisplayController { } /** - * Handler for marker movements due to text being edited. - */ + * Handler for marker movements due to text being edited. + */ _handleMarkerChange( - breakpoint: IBreakpoint, - event: atom$MarkerChangeEvent, - ): void { + breakpoint, + event) + { const path = this._editor.getPath(); if (path == null || path.length === 0) { return; @@ -323,21 +323,21 @@ export default class BreakpointDisplayController { if (!event.isValid) { this._service.removeBreakpoints(breakpoint.getId()); } else if ( - event.oldHeadBufferPosition.row !== event.newHeadBufferPosition.row - ) { + event.oldHeadBufferPosition.row !== event.newHeadBufferPosition.row) + { this._service.updateBreakpoints(breakpoint.uri, { - [breakpoint.getId()]: { - ...breakpoint, + [breakpoint.getId()]: Object.assign({}, + breakpoint, { // VSP is 1-based line numbers. - line: event.newHeadBufferPosition.row + 1, - }, - }); + line: event.newHeadBufferPosition.row + 1 }) }); + + } } - _handleGutterClick(event: Event): void { + _handleGutterClick(event) { // classList isn't in the defs of EventTarget... - const target: HTMLElement = (event.target: any); + const target = event.target; if (target.classList.contains('icon-right')) { return; } @@ -351,12 +351,12 @@ export default class BreakpointDisplayController { // Don't toggle a breakpoint if the user clicked on something in the gutter that is not // the debugger, such as clicking on a line number to select the line. if ( - !target.classList.contains('debugger-shadow-breakpoint-icon') && - !target.classList.contains('debugger-breakpoint-icon') && - !target.classList.contains('debugger-breakpoint-icon-disabled') && - !target.classList.contains('debugger-breakpoint-icon-unresolved') && - !target.classList.contains('debugger-breakpoint-icon-conditional') - ) { + !target.classList.contains('debugger-shadow-breakpoint-icon') && + !target.classList.contains('debugger-breakpoint-icon') && + !target.classList.contains('debugger-breakpoint-icon-disabled') && + !target.classList.contains('debugger-breakpoint-icon-unresolved') && + !target.classList.contains('debugger-breakpoint-icon-conditional')) + { return; } @@ -365,18 +365,18 @@ export default class BreakpointDisplayController { this._service.toggleSourceBreakpoint(path, curLine + 1); if ( - this._service.getModel().getBreakpointAtLine(path, curLine + 1) != null - ) { + this._service.getModel().getBreakpointAtLine(path, curLine + 1) != null) + { // If a breakpoint was added and showDebuggerOnBpSet config setting // is true, show the debugger. - if (featureConfig.get('atom-ide-debugger.showDebuggerOnBpSet')) { + if ((_featureConfig || _load_featureConfig()).default.get('atom-ide-debugger.showDebuggerOnBpSet')) { atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'debugger:show', - { - showOnlyIfHidden: true, - }, - ); + atom.views.getView(atom.workspace), + 'debugger:show', + { + showOnlyIfHidden: true }); + + } } } catch (e) { @@ -384,13 +384,13 @@ export default class BreakpointDisplayController { } } - _getCurrentMouseEventLine(event: Event): number { + _getCurrentMouseEventLine(event) { // $FlowIssue - const bufferPos = bufferPositionForMouseEvent(event, this._editor); + const bufferPos = (0, (_mouseToPosition || _load_mouseToPosition()).bufferPositionForMouseEvent)(event, this._editor); return bufferPos.row; } - _handleGutterMouseMove(event: Event): void { + _handleGutterMouseMove(event) { try { const curLine = this._getCurrentMouseEventLine(event); if (this._isLineOverLastShadowBreakpoint(curLine)) { @@ -405,7 +405,7 @@ export default class BreakpointDisplayController { } } - _handleGutterMouseEnter(event: Event): void { + _handleGutterMouseEnter(event) { window.addEventListener('mousemove', this._boundGlobalMouseMoveHandler); } @@ -413,91 +413,91 @@ export default class BreakpointDisplayController { // The issue is that mouseleave event is sometimes not triggered on the gutter // I(vjeux) and matthewithanm spent multiple entire days trying to figure out // why without success, so this is going to have to do :( - _handleGlobalMouseLeave(event: MouseEvent): void { + _handleGlobalMouseLeave(event) { if (!this._editor) { return; } const view = atom.views.getView(this._editor); const rect = view.getBoundingClientRect(); if ( - event.clientX < rect.left || - event.clientX > rect.right || - event.clientY < rect.top || - event.clientY > rect.bottom - ) { + event.clientX < rect.left || + event.clientX > rect.right || + event.clientY < rect.top || + event.clientY > rect.bottom) + { this._removeLastShadowBreakpoint(); window.removeEventListener( - 'mousemove', - this._boundGlobalMouseMoveHandler, - ); + 'mousemove', + this._boundGlobalMouseMoveHandler); + } } - _handleGutterMouseLeave(event: Event): void { + _handleGutterMouseLeave(event) { this._removeLastShadowBreakpoint(); } - _isLineOverLastShadowBreakpoint(curLine: number): boolean { + _isLineOverLastShadowBreakpoint(curLine) { const shadowBreakpointMarker = this._lastShadowBreakpointMarker; return ( shadowBreakpointMarker != null && - shadowBreakpointMarker.getStartBufferPosition().row === curLine - ); + shadowBreakpointMarker.getStartBufferPosition().row === curLine); + } - _removeLastShadowBreakpoint(): void { + _removeLastShadowBreakpoint() { if (this._lastShadowBreakpointMarker != null) { this._lastShadowBreakpointMarker.destroy(); this._lastShadowBreakpointMarker = null; } } - _createShadowBreakpointAtLine(editor: TextEditor, line: number): void { + _createShadowBreakpointAtLine(editor, line) { const breakpointsAtLine = this._markers.filter( - marker => marker.getStartBufferPosition().row === line, - ); + marker => marker.getStartBufferPosition().row === line); + // Don't create a shadow breakpoint at a line that already has a breakpoint. if (breakpointsAtLine.length === 0) { this._lastShadowBreakpointMarker = this._createBreakpointMarkerAtLine( - line, - true, // isShadow - null, - ); + line, + true, // isShadow + null); + } } _createBreakpointMarkerAtLine( - line: number, - isShadow: boolean, - breakpoint: ?IBreakpoint, - ): atom$Marker { + line, + isShadow, + breakpoint) + { const enabled = breakpoint != null ? breakpoint.enabled : true; const resolved = breakpoint != null ? breakpoint.verified : false; const condition = breakpoint != null ? breakpoint.condition : null; const marker = this._editor.markBufferPosition([line, 0], { - invalidate: 'never', - }); + invalidate: 'never' }); + // If the debugger is not attached, display all breakpoints as resolved. // Once the debugger attaches, it will determine what's actually resolved or not. const unresolved = this._debugging && !resolved; const conditional = condition != null; - const elem: HTMLElement = document.createElement('span'); + const elem = document.createElement('span'); elem.dataset.line = line.toString(); if (breakpoint != null) { elem.dataset.bpId = breakpoint.getId(); } - elem.className = classnames({ + elem.className = (0, (_classnames || _load_classnames()).default)({ 'debugger-breakpoint-icon': !isShadow && enabled && !unresolved, 'debugger-breakpoint-icon-conditional': conditional, 'debugger-breakpoint-icon-nonconditional': !conditional, 'debugger-shadow-breakpoint-icon': isShadow, 'debugger-breakpoint-icon-disabled': !isShadow && !enabled, - 'debugger-breakpoint-icon-unresolved': !isShadow && enabled && unresolved, - }); + 'debugger-breakpoint-icon-unresolved': !isShadow && enabled && unresolved }); + if (!isShadow) { if (!enabled) { @@ -511,10 +511,9 @@ export default class BreakpointDisplayController { if (conditional) { elem.title += ` (Condition: ${condition || ''})`; } - } + }if (!( - invariant(this._gutter != null); - this._gutter.decorateMarker(marker, {item: elem}); + this._gutter != null)) {throw new Error('Invariant violation: "this._gutter != null"');} + this._gutter.decorateMarker(marker, { item: elem }); return marker; - } -} + }}exports.default = BreakpointDisplayController; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/BreakpointManager.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/BreakpointManager.js index e0b00b58..69ba8a5c 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/BreakpointManager.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/BreakpointManager.js @@ -1,63 +1,62 @@ -/** - * 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 - * @format - */ - -import type {IDebugService} from './types'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {observeTextEditors} from 'nuclide-commons-atom/text-editor'; -import BreakpointDisplayController from './BreakpointDisplayController'; - -export default class BreakpointManager { - _service: IDebugService; - _displayControllers: Map; - _disposables: UniversalDisposable; - - constructor(service: IDebugService) { - this._service = service; - this._displayControllers = new Map(); - this._disposables = new UniversalDisposable( - observeTextEditors(this._handleTextEditor.bind(this)), - ); +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _UniversalDisposable; + + + + + + + + + + + + + +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _textEditor; +function _load_textEditor() {return _textEditor = require('nuclide-commons-atom/text-editor');}var _BreakpointDisplayController; +function _load_BreakpointDisplayController() {return _BreakpointDisplayController = _interopRequireDefault(require('./BreakpointDisplayController'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */class BreakpointManager {constructor(service) {this._service = service;this._displayControllers = new Map();this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default( + (0, (_textEditor || _load_textEditor()).observeTextEditors)(this._handleTextEditor.bind(this))); + } - dispose(): void { + dispose() { this._disposables.dispose(); this._displayControllers.forEach(controller => controller.dispose()); this._displayControllers.clear(); } /** - * Used for testing. - */ - getDisplayControllers(): Map { + * Used for testing. + */ + getDisplayControllers() { return this._displayControllers; } /** - * Delegate callback from BreakpointDisplayController. - */ - handleTextEditorDestroyed(controller: BreakpointDisplayController) { + * Delegate callback from BreakpointDisplayController. + */ + handleTextEditorDestroyed(controller) { controller.dispose(); this._displayControllers.delete(controller.getEditor()); } - _handleTextEditor(editor: atom$TextEditor) { + _handleTextEditor(editor) { if (!this._displayControllers.has(editor)) { - const controller = new BreakpointDisplayController( - this, - this._service, - editor, - ); + const controller = new (_BreakpointDisplayController || _load_BreakpointDisplayController()).default( + this, + this._service, + editor); + this._displayControllers.set(editor, controller); } - } -} + }}exports.default = BreakpointManager; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/DebuggerDatatip.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/DebuggerDatatip.js index d385d22a..147f9e49 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/DebuggerDatatip.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/DebuggerDatatip.js @@ -1,58 +1,68 @@ -/** - * 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 - * @format - */ - -import type {Datatip} from 'atom-ide-ui'; -import type {IDebugService} from './types'; - -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import {getDefaultEvaluationExpression} from './evaluationExpression'; -import {DebuggerMode} from './constants'; -import DebuggerDatatipComponent from './ui/DebuggerDatatipComponent'; -import {expressionAsEvaluationResultStream} from './utils'; - -export async function debuggerDatatip( - service: IDebugService, - editor: TextEditor, - position: atom$Point, -): Promise { - if (service.getDebuggerMode() !== DebuggerMode.PAUSED) { - return null; - } - const activeEditor = atom.workspace.getActiveTextEditor(); - if (activeEditor == null) { - return null; - } - const evaluationExpression = getDefaultEvaluationExpression(editor, position); - if (evaluationExpression == null) { - return null; - } - const {expression, range} = evaluationExpression; - const {focusedProcess, focusedStackFrame} = service.viewModel; - if (expression == null || focusedProcess == null) { - // TODO respect session.capabilities.supportsEvaluateForHovers - // and fallback to scopes variables resolution. - return null; - } - const propStream = expressionAsEvaluationResultStream( +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.debuggerDatatip = undefined;var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));let debuggerDatatip = exports.debuggerDatatip = (() => {var _ref = (0, _asyncToGenerator.default)( + + + + + + + + + + + + + + + + + + + + + function* ( + service, + editor, + position) + { + if (service.getDebuggerMode() !== (_constants || _load_constants()).DebuggerMode.PAUSED) { + return null; + } + const activeEditor = atom.workspace.getActiveTextEditor(); + if (activeEditor == null) { + return null; + } + const evaluationExpression = (0, (_evaluationExpression || _load_evaluationExpression()).getDefaultEvaluationExpression)(editor, position); + if (evaluationExpression == null) { + return null; + } + const { expression, range } = evaluationExpression; + const { focusedProcess, focusedStackFrame } = service.viewModel; + if (expression == null || focusedProcess == null) { + // TODO respect session.capabilities.supportsEvaluateForHovers + // and fallback to scopes variables resolution. + return null; + } + const propStream = (0, (_utils || _load_utils()).expressionAsEvaluationResultStream)( service.createExpression(expression), focusedProcess, focusedStackFrame, - 'hover', - ).map(evaluationResult => ({ - expression, - evaluationResult, - })); - return { - component: bindObservableAsProps(propStream, DebuggerDatatipComponent), - range, - }; -} + 'hover'). + map(function (evaluationResult) {return { + expression, + evaluationResult };}); + + return { + component: (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)(propStream, (_DebuggerDatatipComponent || _load_DebuggerDatatipComponent()).default), + range }; + + });return function debuggerDatatip(_x, _x2, _x3) {return _ref.apply(this, arguments);};})(); /** + * 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. + * + * + * @format + */var _bindObservableAsProps;function _load_bindObservableAsProps() {return _bindObservableAsProps = require('nuclide-commons-ui/bindObservableAsProps');}var _evaluationExpression;function _load_evaluationExpression() {return _evaluationExpression = require('./evaluationExpression');}var _constants;function _load_constants() {return _constants = require('./constants');}var _DebuggerDatatipComponent;function _load_DebuggerDatatipComponent() {return _DebuggerDatatipComponent = _interopRequireDefault(require('./ui/DebuggerDatatipComponent'));}var _utils;function _load_utils() {return _utils = require('./utils');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/DebuggerUiModel.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/DebuggerUiModel.js index 5cf23722..96f08e84 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/DebuggerUiModel.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/DebuggerUiModel.js @@ -1,64 +1,64 @@ -/** - * 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 - * @format - */ - -import type { - DebuggerLaunchAttachProvider, - NuclideDebuggerProvider, -} from 'nuclide-debugger-common'; -import type {IDebugService} from './types'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Emitter} from 'atom'; -import nuclideUri from 'nuclide-commons/nuclideUri'; - -export const WORKSPACE_VIEW_URI = 'atom://nuclide/debugger'; - -const CONNECTIONS_UPDATED_EVENT = 'CONNECTIONS_UPDATED_EVENT'; -const PROVIDERS_UPDATED_EVENT = 'PROVIDERS_UPDATED_EVENT'; - -/** - * Atom ViewProvider compatible model object. - */ -export default class DebuggerModel { - _disposables: UniversalDisposable; - _service: IDebugService; - _emitter: Emitter; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.WORKSPACE_VIEW_URI = undefined;var _UniversalDisposable; + + + + + + + + + + + + + + + + +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));} +var _atom = require('atom');var _nuclideUri; +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +const WORKSPACE_VIEW_URI = exports.WORKSPACE_VIEW_URI = 'atom://nuclide/debugger'; /** + * 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. + * + * + * @format + */const CONNECTIONS_UPDATED_EVENT = 'CONNECTIONS_UPDATED_EVENT';const PROVIDERS_UPDATED_EVENT = 'PROVIDERS_UPDATED_EVENT'; /** + * Atom ViewProvider compatible model object. + */class DebuggerModel { // Debugger providers - _debuggerProviders: Set; - _connections: Array; - constructor(service: IDebugService) { + + + constructor(service) { this._service = service; - this._emitter = new Emitter(); + this._emitter = new _atom.Emitter(); this._debuggerProviders = new Set(); // There is always a local connection. this._connections = ['local']; - this._disposables = new UniversalDisposable(this._listenForProjectChange()); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(this._listenForProjectChange()); } - _listenForProjectChange(): IDisposable { + _listenForProjectChange() { return atom.project.onDidChangePaths(() => { this._updateConnections(); }); } /** - * Utility for getting refreshed connections. - * TODO: refresh connections when new directories are removed/added in file-tree. - */ - _updateConnections(): void { + * Utility for getting refreshed connections. + * TODO: refresh connections when new directories are removed/added in file-tree. + */ + _updateConnections() { const connections = this._getRemoteConnections(); // Always have one single local connection. connections.push('local'); @@ -67,59 +67,59 @@ export default class DebuggerModel { } /** - * Get remote connections without duplication. - */ - _getRemoteConnections(): Array { + * Get remote connections without duplication. + */ + _getRemoteConnections() { // TODO: move this logic into RemoteConnection package. - return atom.project - .getPaths() - .filter(path => { - return nuclideUri.isRemote(path); - }) - .map(remotePath => { - const {hostname} = nuclideUri.parseRemoteUri(remotePath); - return nuclideUri.createRemoteUri(hostname, '/'); - }) - .filter((path, index, inputArray) => { - return inputArray.indexOf(path) === index; - }); + return atom.project. + getPaths(). + filter(path => { + return (_nuclideUri || _load_nuclideUri()).default.isRemote(path); + }). + map(remotePath => { + const { hostname } = (_nuclideUri || _load_nuclideUri()).default.parseRemoteUri(remotePath); + return (_nuclideUri || _load_nuclideUri()).default.createRemoteUri(hostname, '/'); + }). + filter((path, index, inputArray) => { + return inputArray.indexOf(path) === index; + }); } dispose() { this._disposables.dispose(); } - addDebuggerProvider(provider: NuclideDebuggerProvider): void { + addDebuggerProvider(provider) { this._debuggerProviders.add(provider); this._emitter.emit(PROVIDERS_UPDATED_EVENT); } - removeDebuggerProvider(provider: NuclideDebuggerProvider): void { + removeDebuggerProvider(provider) { this._debuggerProviders.delete(provider); } /** - * Subscribe to new connection updates from DebuggerActions. - */ - onConnectionsUpdated(callback: () => void): IDisposable { + * Subscribe to new connection updates from DebuggerActions. + */ + onConnectionsUpdated(callback) { return this._emitter.on(CONNECTIONS_UPDATED_EVENT, callback); } - onProvidersUpdated(callback: () => void): IDisposable { + onProvidersUpdated(callback) { return this._emitter.on(PROVIDERS_UPDATED_EVENT, callback); } - getConnections(): Array { + getConnections() { return this._connections; } /** - * Return available launch/attach provider for input connection. - * Caller is responsible for disposing the results. - */ + * Return available launch/attach provider for input connection. + * Caller is responsible for disposing the results. + */ getLaunchAttachProvidersForConnection( - connection: string, - ): Array { + connection) + { const availableLaunchAttachProviders = []; for (const provider of this._debuggerProviders) { const launchAttachProvider = provider.getLaunchAttachProvider(connection); @@ -128,5 +128,4 @@ export default class DebuggerModel { } } return availableLaunchAttachProviders; - } -} + }}exports.default = DebuggerModel; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/RemoteControlService.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/RemoteControlService.js index 5c1aab35..36968288 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/RemoteControlService.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/RemoteControlService.js @@ -1,94 +1,103 @@ -/** - * 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 - * @format - */ - -import type {Observable} from 'rxjs'; -import type {IDebugService} from './types'; -import type { - IProcessConfig, - IVspInstance, - VspProcessInfo, -} from 'nuclide-debugger-common'; -import * as DebugProtocol from 'vscode-debugprotocol'; - -import {DebuggerMode} from './constants'; -import invariant from 'assert'; - -export default class RemoteControlService { - _service: IDebugService; - - constructor(service: IDebugService) { +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _vscodeDebugprotocol; + + + + + + + + + + + + + + + + + + +function _load_vscodeDebugprotocol() {return _vscodeDebugprotocol = _interopRequireWildcard(require('vscode-debugprotocol'));}var _constants; + +function _load_constants() {return _constants = require('./constants');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + + +class RemoteControlService { + + + constructor(service) { this._service = service; } - async startDebugging(processInfo: VspProcessInfo): Promise { - const instance = await this.startVspDebugging( - processInfo.getProcessConfig(), - ); - - processInfo.setVspDebuggerInstance(instance); - - const {focusedProcess} = this._service.viewModel; - invariant(focusedProcess != null); - const disposable = this._service.viewModel.onDidFocusProcess(() => { - if ( - !this._service - .getModel() - .getProcesses() - .includes(focusedProcess) - ) { - processInfo.dispose(); - disposable.dispose(); - } - }); - } + startDebugging(processInfo) {var _this = this;return (0, _asyncToGenerator.default)(function* () { + const instance = yield _this.startVspDebugging( + processInfo.getProcessConfig()); + - async startVspDebugging(config: IProcessConfig): Promise { - await this._service.startDebugging(config); - - const {viewModel} = this._service; - const {focusedProcess} = viewModel; - invariant(focusedProcess != null); - - const isFocusedProcess = (): boolean => { - return ( - this._service.getDebuggerMode() !== DebuggerMode.STOPPED && - viewModel.focusedProcess === focusedProcess - ); - }; - - const customRequest = async ( - request: string, - args: any, - ): Promise => { - if (!isFocusedProcess()) { - throw new Error( - 'Cannot send custom requests to a no longer active debug session!', - ); - } - return focusedProcess.session.custom(request, args); - }; - - const observeCustomEvents = (): Observable => { - if (!isFocusedProcess()) { - throw new Error( - 'Cannot send custom requests to a no longer active debug session!', - ); - } - return focusedProcess.session.observeCustomEvents(); - }; - - return Object.freeze({ - customRequest, - observeCustomEvents, - }); + processInfo.setVspDebuggerInstance(instance); + + const { focusedProcess } = _this._service.viewModel;if (!( + focusedProcess != null)) {throw new Error('Invariant violation: "focusedProcess != null"');} + const disposable = _this._service.viewModel.onDidFocusProcess(function () { + if ( + !_this._service. + getModel(). + getProcesses(). + includes(focusedProcess)) + { + processInfo.dispose(); + disposable.dispose(); + } + });})(); } -} + + startVspDebugging(config) {var _this2 = this;return (0, _asyncToGenerator.default)(function* () { + yield _this2._service.startDebugging(config); + + const { viewModel } = _this2._service; + const { focusedProcess } = viewModel;if (!( + focusedProcess != null)) {throw new Error('Invariant violation: "focusedProcess != null"');} + + const isFocusedProcess = function () { + return ( + _this2._service.getDebuggerMode() !== (_constants || _load_constants()).DebuggerMode.STOPPED && + viewModel.focusedProcess === focusedProcess); + + }; + + const customRequest = (() => {var _ref = (0, _asyncToGenerator.default)(function* ( + request, + args) + { + if (!isFocusedProcess()) { + throw new Error( + 'Cannot send custom requests to a no longer active debug session!'); + + } + return focusedProcess.session.custom(request, args); + });return function customRequest(_x, _x2) {return _ref.apply(this, arguments);};})(); + + const observeCustomEvents = function () { + if (!isFocusedProcess()) { + throw new Error( + 'Cannot send custom requests to a no longer active debug session!'); + + } + return focusedProcess.session.observeCustomEvents(); + }; + + return Object.freeze({ + customRequest, + observeCustomEvents });})(); + + }}exports.default = RemoteControlService; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/constants.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/constants.js index cd8d1eeb..1fd45ae6 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/constants.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/constants.js @@ -1,18 +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 - * @format - */ - -import type {DebuggerModeType} from './types'; - -export const AnalyticsEvents = Object.freeze({ +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); + + + + + + + + + + + + + +const AnalyticsEvents = exports.AnalyticsEvents = Object.freeze({ DEBUGGER_BREAKPOINT_ADD: 'debugger-breakpoint-add', DEBUGGER_BREAKPOINT_DELETE: 'debugger-breakpoint-delete', DEBUGGER_BREAKPOINT_DELETE_ALL: 'debugger-breakpoint-delete-all', @@ -38,28 +38,28 @@ export const AnalyticsEvents = Object.freeze({ DEBUGGER_WATCH_REMOVE_EXPRESSION: 'debugger-watch-remove-expression', DEBUGGER_WATCH_UPDATE_EXPRESSION: 'debugger-watch-update-expression', DEBUGGER_EDIT_BREAKPOINT_FROM_ICON: 'debugger-edit-breakpoint-from-icon', - DEBUGGER_DELETE_BREAKPOINT_FROM_ICON: 'debugger-delete-breakpoint-from-icon', -}); - -export const DebuggerMode = Object.freeze({ - STARTING: 'starting', - RUNNING: 'running', - PAUSED: 'paused', - STOPPED: 'stopped', - STOPPING: 'stopping', -}); - + DEBUGGER_DELETE_BREAKPOINT_FROM_ICON: 'debugger-delete-breakpoint-from-icon' }); /** + * 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. + * + * + * @format + */const DebuggerMode = exports.DebuggerMode = Object.freeze({ STARTING: 'starting', RUNNING: 'running', PAUSED: 'paused', STOPPED: 'stopped', STOPPING: 'stopping' }); // This is to work around flow's missing support of enums. -(DebuggerMode: {[key: string]: DebuggerModeType}); +DebuggerMode; -export const DEBUGGER_PANELS_DEFAULT_LOCATION = 'right'; -export const DEBUGGER_PANELS_DEFAULT_WIDTH_PX = 500; +const DEBUGGER_PANELS_DEFAULT_LOCATION = exports.DEBUGGER_PANELS_DEFAULT_LOCATION = 'right'; +const DEBUGGER_PANELS_DEFAULT_WIDTH_PX = exports.DEBUGGER_PANELS_DEFAULT_WIDTH_PX = 500; -export const BreakpointEventReasons = Object.freeze({ +const BreakpointEventReasons = exports.BreakpointEventReasons = Object.freeze({ NEW: 'new', CHANGED: 'changed', - REMOVED: 'removed', -}); + REMOVED: 'removed' }); + -export const UNKNOWN_SOURCE = 'Unknown'; -export const DEBUG_SOURCES_URI = 'atom://debug-sources'; +const UNKNOWN_SOURCE = exports.UNKNOWN_SOURCE = 'Unknown'; +const DEBUG_SOURCES_URI = exports.DEBUG_SOURCES_URI = 'atom://debug-sources'; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/evaluationExpression.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/evaluationExpression.js index 4cd8aea1..066b5188 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/evaluationExpression.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/evaluationExpression.js @@ -1,54 +1,54 @@ -/** - * 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 - * @format - */ - -/** -Originally copied from https://github.com/Microsoft/vscode/blob/b34f17350f2d20dbbbfdb26df91dd50bb9160900/src/vs/workbench/parts/debug/electron-browser/debugHover.ts#L125-L166 - -MIT License - -Copyright (c) 2015 - present Microsoft Corporation - -All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -import {Range} from 'atom'; - -export function getDefaultEvaluationExpression( - editor: atom$TextEditor, - position: atom$Point, -): ?{ - expression: string, - range: atom$Range, -} { +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +getDefaultEvaluationExpression = getDefaultEvaluationExpression;var _atom = require('atom');function getDefaultEvaluationExpression( +editor, +position) + + + +{ const lineContent = editor.lineTextForBufferRow(position.row); - let matchingExpression: ?string; + let matchingExpression; let startOffset = 0; // Some example supported expressions: myVar.prop, a.b.c.d, myVar?.prop, myVar->prop, MyClass::StaticProp, *myVar @@ -57,7 +57,7 @@ export function getDefaultEvaluationExpression( let result; // First find the full expression under the cursor - while ((result = expression.exec(lineContent))) { + while (result = expression.exec(lineContent)) { const start = result.index + 1; const end = start + result[0].length; @@ -73,12 +73,12 @@ export function getDefaultEvaluationExpression( if (matchingExpression != null) { const subExpression = /\w+/g; let subExpressionResult; - while ((subExpressionResult = subExpression.exec(matchingExpression))) { + while (subExpressionResult = subExpression.exec(matchingExpression)) { const subEnd = - subExpressionResult.index + - 1 + - startOffset + - subExpressionResult[0].length; + subExpressionResult.index + + 1 + + startOffset + + subExpressionResult[0].length; if (subEnd >= position.column + 1) { break; } @@ -86,9 +86,9 @@ export function getDefaultEvaluationExpression( if (subExpressionResult) { matchingExpression = matchingExpression.substring( - 0, - subExpression.lastIndex, - ); + 0, + subExpression.lastIndex); + } } @@ -98,9 +98,45 @@ export function getDefaultEvaluationExpression( return { expression: matchingExpression, - range: new Range( - [position.row, startOffset - 1], - [position.row, startOffset + matchingExpression.length - 1], - ), - }; -} + range: new _atom.Range( + [position.row, startOffset - 1], + [position.row, startOffset + matchingExpression.length - 1]) }; + + +} /** + * 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. + * + * + * @format + */ /** + Originally copied from https://github.com/Microsoft/vscode/blob/b34f17350f2d20dbbbfdb26df91dd50bb9160900/src/vs/workbench/parts/debug/electron-browser/debugHover.ts#L125-L166 + + MIT License + + Copyright (c) 2015 - present Microsoft Corporation + + All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/logger.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/logger.js index 2519dd84..65354d44 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/logger.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/logger.js @@ -1,16 +1,25 @@ -/** - * 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 - * @format - */ - -import {getLogger} from 'log4js'; - -const DEBUGGER_LOGGER_CATEGORY = 'atom-debugger'; -export default getLogger(DEBUGGER_LOGGER_CATEGORY); +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _log4js; + + + + + + + + + + + +function _load_log4js() {return _log4js = require('log4js');} + +const DEBUGGER_LOGGER_CATEGORY = 'atom-debugger'; /** + * 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. + * + * + * @format + */exports.default = (0, (_log4js || _load_log4js()).getLogger)(DEBUGGER_LOGGER_CATEGORY); \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/main.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/main.js index 92b772d0..a82f521e 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/main.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/main.js @@ -1,366 +1,366 @@ -/** - * 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 - * @format - */ - -import type { - DebuggerConfigAction, - DebuggerLaunchAttachProvider, - NuclideDebuggerProvider, - DebuggerConfigurationProvider, -} from 'nuclide-debugger-common'; -import type { - ConsoleService, - DatatipProvider, - DatatipService, - RegisterExecutorFunction, - TerminalApi, -} from 'atom-ide-ui'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {SerializedState, IBreakpoint} from './types'; - -import {observeRemovedHostnames} from 'nuclide-commons-atom/projects'; -import BreakpointManager from './BreakpointManager'; -import {AnalyticsEvents, DebuggerMode} from './constants'; -import BreakpointConfigComponent from './ui/BreakpointConfigComponent'; -import createPackage from 'nuclide-commons-atom/createPackage'; -import {getLineForEvent} from './utils'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import invariant from 'assert'; -import {track} from 'nuclide-commons/analytics'; -import RemoteControlService from './RemoteControlService'; -import DebuggerUiModel from './DebuggerUiModel'; -import DebugService from './vsp/DebugService'; -import {debuggerDatatip} from './DebuggerDatatip'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import DebuggerLaunchAttachUI from './ui/DebuggerLaunchAttachUI'; -import {renderReactRoot} from 'nuclide-commons-ui/renderReactRoot'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import { - setNotificationService, - setConsoleService, - setConsoleRegisterExecutor, - setDatatipService, - setTerminalService, - setRpcService, - addDebugConfigurationProvider, -} from './AtomServiceContainer'; -import {wordAtPosition, trimRange} from 'nuclide-commons-atom/range'; -import DebuggerLayoutManager from './ui/DebuggerLayoutManager'; -import DebuggerPaneViewModel from './ui/DebuggerPaneViewModel'; -import DebuggerPaneContainerViewModel from './ui/DebuggerPaneContainerViewModel'; -import os from 'os'; -import nullthrows from 'nullthrows'; -import ReactMountRootElement from 'nuclide-commons-ui/ReactMountRootElement'; -import {makeToolbarButtonSpec} from 'nuclide-commons-ui/ToolbarUtils'; - -const DATATIP_PACKAGE_NAME = 'debugger-datatip'; - -class Activation { - _disposables: UniversalDisposable; - _uiModel: DebuggerUiModel; - _breakpointManager: BreakpointManager; - _service: DebugService; - _layoutManager: DebuggerLayoutManager; - _selectedDebugConnection: ?string; - _visibleLaunchAttachDialogMode: ?DebuggerConfigAction; - _lauchAttachDialogCloser: ?() => void; - _connectionProviders: Map>; - - constructor(state: ?SerializedState) { - atom.views.addViewProvider(DebuggerPaneViewModel, createDebuggerView); - atom.views.addViewProvider( - DebuggerPaneContainerViewModel, - createDebuggerView, - ); - this._service = new DebugService(state); - this._uiModel = new DebuggerUiModel(this._service); - this._breakpointManager = new BreakpointManager(this._service); +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _projects; + + + + + + + + + + + + + + + + + + + + + + + + + + + +function _load_projects() {return _projects = require('nuclide-commons-atom/projects');}var _BreakpointManager; +function _load_BreakpointManager() {return _BreakpointManager = _interopRequireDefault(require('./BreakpointManager'));}var _constants; +function _load_constants() {return _constants = require('./constants');}var _BreakpointConfigComponent; +function _load_BreakpointConfigComponent() {return _BreakpointConfigComponent = _interopRequireDefault(require('./ui/BreakpointConfigComponent'));}var _createPackage; +function _load_createPackage() {return _createPackage = _interopRequireDefault(require('nuclide-commons-atom/createPackage'));}var _utils; +function _load_utils() {return _utils = require('./utils');}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _analytics; + +function _load_analytics() {return _analytics = require('nuclide-commons/analytics');}var _RemoteControlService; +function _load_RemoteControlService() {return _RemoteControlService = _interopRequireDefault(require('./RemoteControlService'));}var _DebuggerUiModel; +function _load_DebuggerUiModel() {return _DebuggerUiModel = _interopRequireDefault(require('./DebuggerUiModel'));}var _DebugService; +function _load_DebugService() {return _DebugService = _interopRequireDefault(require('./vsp/DebugService'));}var _DebuggerDatatip; +function _load_DebuggerDatatip() {return _DebuggerDatatip = require('./DebuggerDatatip');} +var _react = _interopRequireWildcard(require('react')); +var _reactDom = _interopRequireDefault(require('react-dom'));var _DebuggerLaunchAttachUI; +function _load_DebuggerLaunchAttachUI() {return _DebuggerLaunchAttachUI = _interopRequireDefault(require('./ui/DebuggerLaunchAttachUI'));}var _renderReactRoot; +function _load_renderReactRoot() {return _renderReactRoot = require('nuclide-commons-ui/renderReactRoot');}var _nuclideUri; +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));}var _AtomServiceContainer; +function _load_AtomServiceContainer() {return _AtomServiceContainer = require('./AtomServiceContainer');}var _range; + + + + + + + + +function _load_range() {return _range = require('nuclide-commons-atom/range');}var _DebuggerLayoutManager; +function _load_DebuggerLayoutManager() {return _DebuggerLayoutManager = _interopRequireDefault(require('./ui/DebuggerLayoutManager'));}var _DebuggerPaneViewModel; +function _load_DebuggerPaneViewModel() {return _DebuggerPaneViewModel = _interopRequireDefault(require('./ui/DebuggerPaneViewModel'));}var _DebuggerPaneContainerViewModel; +function _load_DebuggerPaneContainerViewModel() {return _DebuggerPaneContainerViewModel = _interopRequireDefault(require('./ui/DebuggerPaneContainerViewModel'));} +var _os = _interopRequireDefault(require('os'));var _nullthrows; +function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));}var _ReactMountRootElement; +function _load_ReactMountRootElement() {return _ReactMountRootElement = _interopRequireDefault(require('nuclide-commons-ui/ReactMountRootElement'));}var _ToolbarUtils; +function _load_ToolbarUtils() {return _ToolbarUtils = require('nuclide-commons-ui/ToolbarUtils');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */const DATATIP_PACKAGE_NAME = 'debugger-datatip';class Activation { + + + + + constructor(state) { + atom.views.addViewProvider((_DebuggerPaneViewModel || _load_DebuggerPaneViewModel()).default, createDebuggerView); + atom.views.addViewProvider((_DebuggerPaneContainerViewModel || _load_DebuggerPaneContainerViewModel()).default, + + createDebuggerView); + + this._service = new (_DebugService || _load_DebugService()).default(state); + this._uiModel = new (_DebuggerUiModel || _load_DebuggerUiModel()).default(this._service); + this._breakpointManager = new (_BreakpointManager || _load_BreakpointManager()).default(this._service); this._selectedDebugConnection = null; this._visibleLaunchAttachDialogMode = null; this._lauchAttachDialogCloser = null; this._connectionProviders = new Map(); - this._layoutManager = new DebuggerLayoutManager(this._service, state); + this._layoutManager = new (_DebuggerLayoutManager || _load_DebuggerLayoutManager()).default(this._service, state); // Manually manipulate the `Debugger` top level menu order. const insertIndex = atom.menu.template.findIndex( - item => item.role === 'window' || item.role === 'help', - ); + item => item.role === 'window' || item.role === 'help'); + if (insertIndex !== -1) { const deuggerIndex = atom.menu.template.findIndex( - item => item.label === 'Debugger', - ); + item => item.label === 'Debugger'); + const menuItem = atom.menu.template.splice(deuggerIndex, 1)[0]; const newIndex = - insertIndex > deuggerIndex ? insertIndex - 1 : insertIndex; + insertIndex > deuggerIndex ? insertIndex - 1 : insertIndex; atom.menu.template.splice(newIndex, 0, menuItem); atom.menu.update(); } - const removedHostnames = observeRemovedHostnames(); - - this._disposables = new UniversalDisposable( - this._layoutManager, - this._service, - this._uiModel, - this._breakpointManager, - removedHostnames.subscribe(hostname => { - const debuggerProcess = this._service.viewModel.focusedProcess; - if (debuggerProcess == null) { - return; // Nothing to do if we're not debugging. - } - const debuggeeTargetUri = debuggerProcess.configuration.targetUri; - if (nuclideUri.isLocal(debuggeeTargetUri)) { - return; // Nothing to do if our debug session is local. - } - if (nuclideUri.getHostname(debuggeeTargetUri) === hostname) { - this._service.stopProcess(); - } - }), - this._uiModel.onConnectionsUpdated(() => { - const newConnections = this._uiModel.getConnections(); - const keys = Array.from(this._connectionProviders.keys()); - - const removedConnections = keys.filter( - connection => - newConnections.find(item => item === connection) == null, - ); - const addedConnections = newConnections.filter( - connection => keys.find(item => item === connection) == null, - ); - - for (const key of removedConnections) { - for (const provider of this._connectionProviders.get(key) || []) { - provider.dispose(); - } + const removedHostnames = (0, (_projects || _load_projects()).observeRemovedHostnames)(); + + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default( + this._layoutManager, + this._service, + this._uiModel, + this._breakpointManager, + removedHostnames.subscribe(hostname => { + const debuggerProcess = this._service.viewModel.focusedProcess; + if (debuggerProcess == null) { + return; // Nothing to do if we're not debugging. + } + const debuggeeTargetUri = debuggerProcess.configuration.targetUri; + if ((_nuclideUri || _load_nuclideUri()).default.isLocal(debuggeeTargetUri)) { + return; // Nothing to do if our debug session is local. + } + if ((_nuclideUri || _load_nuclideUri()).default.getHostname(debuggeeTargetUri) === hostname) { + this._service.stopProcess(); + } + }), + this._uiModel.onConnectionsUpdated(() => { + const newConnections = this._uiModel.getConnections(); + const keys = Array.from(this._connectionProviders.keys()); - this._connectionProviders.delete(key); - } + const removedConnections = keys.filter( + connection => + newConnections.find(item => item === connection) == null); - for (const connection of addedConnections) { - this._setProvidersForConnection(connection); - } - }), - this._uiModel.onProvidersUpdated(() => { - const connections = this._uiModel.getConnections(); - for (const connection of connections) { - this._setProvidersForConnection(connection); + const addedConnections = newConnections.filter( + connection => keys.find(item => item === connection) == null); + + + for (const key of removedConnections) { + for (const provider of this._connectionProviders.get(key) || []) { + provider.dispose(); } - }), - // Commands. - atom.commands.add('atom-workspace', { - 'debugger:show-attach-dialog': () => { - const boundFn = this._showLaunchAttachDialog.bind(this); - boundFn('attach'); - }, - }), - atom.commands.add('atom-workspace', { - 'debugger:show-launch-dialog': () => { - const boundFn = this._showLaunchAttachDialog.bind(this); - boundFn('launch'); - }, - }), - atom.commands.add('atom-workspace', { - 'debugger:continue-debugging': this._continue.bind(this), - }), - atom.commands.add('atom-workspace', { - 'debugger:stop-debugging': this._stop.bind(this), - }), - atom.commands.add('atom-workspace', { - 'debugger:restart-debugging': this._restart.bind(this), - }), - atom.commands.add('atom-workspace', { - 'debugger:step-over': this._stepOver.bind(this), - }), - atom.commands.add('atom-workspace', { - 'debugger:step-into': this._stepInto.bind(this), - }), - atom.commands.add('atom-workspace', { - 'debugger:step-out': this._stepOut.bind(this), - }), - atom.commands.add('atom-workspace', { - 'debugger:toggle-breakpoint': this._toggleBreakpoint.bind(this), - }), - atom.commands.add('atom-workspace', { - 'debugger:toggle-breakpoint-enabled': this._toggleBreakpointEnabled.bind( - this, - ), - }), - atom.commands.add('atom-workspace', { - 'debugger:edit-breakpoint': this._configureBreakpoint.bind(this), - }), - atom.commands.add('.debugger-thread-list-item', { - 'debugger:terminate-thread': this._terminateThread.bind(this), - }), - atom.commands.add('atom-workspace', { - 'debugger:remove-all-breakpoints': this._deleteAllBreakpoints.bind( - this, - ), - }), - atom.commands.add('atom-workspace', { - 'debugger:enable-all-breakpoints': this._enableAllBreakpoints.bind( - this, - ), - }), - atom.commands.add('atom-workspace', { - 'debugger:disable-all-breakpoints': this._disableAllBreakpoints.bind( - this, - ), - }), - atom.commands.add('atom-workspace', { - 'debugger:remove-breakpoint': this._deleteBreakpoint.bind(this), - }), - atom.commands.add('atom-workspace', { - 'debugger:add-to-watch': this._addToWatch.bind(this), - }), - atom.commands.add('atom-workspace', { - 'debugger:run-to-location': this._runToLocation.bind(this), - }), - atom.commands.add('.debugger-expression-value-list', { - 'debugger:copy-debugger-expression-value': this._copyDebuggerExpressionValue.bind( - this, - ), - }), - atom.commands.add('atom-workspace', { - 'debugger:copy-debugger-callstack': this._copyDebuggerCallstack.bind( - this, - ), - }), - // Context Menu Items. - atom.contextMenu.add({ - '.debugger-breakpoint-list': [ - { - label: 'Enable All Breakpoints', - command: 'debugger:enable-all-breakpoints', - }, - { - label: 'Disable All Breakpoints', - command: 'debugger:disable-all-breakpoints', - }, - { - label: 'Remove All Breakpoints', - command: 'debugger:remove-all-breakpoints', - }, - {type: 'separator'}, - ], - '.debugger-breakpoint': [ - { - label: 'Edit breakpoint...', - command: 'debugger:edit-breakpoint', - shouldDisplay: event => { - const bp = this._getBreakpointFromEvent(event); - return bp != null && this._supportsConditionalBreakpoints(); - }, - }, - { - label: 'Remove Breakpoint', - command: 'debugger:remove-breakpoint', - }, - {type: 'separator'}, - ], - '.debugger-thread-list-item': [ - { - label: 'Terminate thread', - command: 'debugger:terminate-thread', - shouldDisplay: event => { - const target: HTMLElement = event.target; - if (target.dataset.threadid) { - const threadId = parseInt(target.dataset.threadid, 10); - if (!Number.isNaN(threadId)) { - return this._supportsTerminateThreadsRequest(); - } - } + + this._connectionProviders.delete(key); + } + + for (const connection of addedConnections) { + this._setProvidersForConnection(connection); + } + }), + this._uiModel.onProvidersUpdated(() => { + const connections = this._uiModel.getConnections(); + for (const connection of connections) { + this._setProvidersForConnection(connection); + } + }), + // Commands. + atom.commands.add('atom-workspace', { + 'debugger:show-attach-dialog': () => { + const boundFn = this._showLaunchAttachDialog.bind(this); + boundFn('attach'); + } }), + + atom.commands.add('atom-workspace', { + 'debugger:show-launch-dialog': () => { + const boundFn = this._showLaunchAttachDialog.bind(this); + boundFn('launch'); + } }), + + atom.commands.add('atom-workspace', { + 'debugger:continue-debugging': this._continue.bind(this) }), + + atom.commands.add('atom-workspace', { + 'debugger:stop-debugging': this._stop.bind(this) }), + + atom.commands.add('atom-workspace', { + 'debugger:restart-debugging': this._restart.bind(this) }), + + atom.commands.add('atom-workspace', { + 'debugger:step-over': this._stepOver.bind(this) }), + + atom.commands.add('atom-workspace', { + 'debugger:step-into': this._stepInto.bind(this) }), + + atom.commands.add('atom-workspace', { + 'debugger:step-out': this._stepOut.bind(this) }), + + atom.commands.add('atom-workspace', { + 'debugger:toggle-breakpoint': this._toggleBreakpoint.bind(this) }), + + atom.commands.add('atom-workspace', { + 'debugger:toggle-breakpoint-enabled': this._toggleBreakpointEnabled.bind( + this) }), + + + atom.commands.add('atom-workspace', { + 'debugger:edit-breakpoint': this._configureBreakpoint.bind(this) }), + + atom.commands.add('.debugger-thread-list-item', { + 'debugger:terminate-thread': this._terminateThread.bind(this) }), + + atom.commands.add('atom-workspace', { + 'debugger:remove-all-breakpoints': this._deleteAllBreakpoints.bind( + this) }), + + + atom.commands.add('atom-workspace', { + 'debugger:enable-all-breakpoints': this._enableAllBreakpoints.bind( + this) }), + + + atom.commands.add('atom-workspace', { + 'debugger:disable-all-breakpoints': this._disableAllBreakpoints.bind( + this) }), + + + atom.commands.add('atom-workspace', { + 'debugger:remove-breakpoint': this._deleteBreakpoint.bind(this) }), + + atom.commands.add('atom-workspace', { + 'debugger:add-to-watch': this._addToWatch.bind(this) }), + + atom.commands.add('atom-workspace', { + 'debugger:run-to-location': this._runToLocation.bind(this) }), + + atom.commands.add('.debugger-expression-value-list', { + 'debugger:copy-debugger-expression-value': this._copyDebuggerExpressionValue.bind( + this) }), + + + atom.commands.add('atom-workspace', { + 'debugger:copy-debugger-callstack': this._copyDebuggerCallstack.bind( + this) }), + + + // Context Menu Items. + atom.contextMenu.add({ + '.debugger-breakpoint-list': [ + { + label: 'Enable All Breakpoints', + command: 'debugger:enable-all-breakpoints' }, + + { + label: 'Disable All Breakpoints', + command: 'debugger:disable-all-breakpoints' }, + + { + label: 'Remove All Breakpoints', + command: 'debugger:remove-all-breakpoints' }, + + { type: 'separator' }], + + '.debugger-breakpoint': [ + { + label: 'Edit breakpoint...', + command: 'debugger:edit-breakpoint', + shouldDisplay: event => { + const bp = this._getBreakpointFromEvent(event); + return bp != null && this._supportsConditionalBreakpoints(); + } }, + + { + label: 'Remove Breakpoint', + command: 'debugger:remove-breakpoint' }, + + { type: 'separator' }], + + '.debugger-thread-list-item': [ + { + label: 'Terminate thread', + command: 'debugger:terminate-thread', + shouldDisplay: event => { + const target = event.target; + if (target.dataset.threadid) { + const threadId = parseInt(target.dataset.threadid, 10); + if (!Number.isNaN(threadId)) { + return this._supportsTerminateThreadsRequest(); + } + } + return false; + } }], + + + '.debugger-callstack-table': [ + { + label: 'Copy Callstack', + command: 'debugger:copy-debugger-callstack' }], + + + '.debugger-expression-value-list': [ + { + label: 'Copy', + command: 'debugger:copy-debugger-expression-value' }], + + + 'atom-text-editor': [ + { type: 'separator' }, + { + label: 'Debugger', + submenu: [ + { + label: 'Toggle Breakpoint', + command: 'debugger:toggle-breakpoint' }, + + { + label: 'Toggle Breakpoint enabled/disabled', + command: 'debugger:toggle-breakpoint-enabled', + shouldDisplay: event => + this._executeWithEditorPath( + event, + (filePath, line) => + this._service. + getModel(). + getBreakpointAtLine(filePath, line) != null) || + false }, + + { + label: 'Edit Breakpoint...', + command: 'debugger:edit-breakpoint', + shouldDisplay: event => + this._executeWithEditorPath(event, (filePath, line) => { + const bp = this._service. + getModel(). + getBreakpointAtLine(filePath, line); + return bp != null && this._supportsConditionalBreakpoints(); + }) || false }, + + { + label: 'Add to Watch', + command: 'debugger:add-to-watch', + shouldDisplay: event => { + const textEditor = atom.workspace.getActiveTextEditor(); + if ( + this._service.getDebuggerMode() === (_constants || _load_constants()).DebuggerMode.STOPPED || + textEditor == null) + { return false; - }, - }, - ], - '.debugger-callstack-table': [ - { - label: 'Copy Callstack', - command: 'debugger:copy-debugger-callstack', - }, - ], - '.debugger-expression-value-list': [ - { - label: 'Copy', - command: 'debugger:copy-debugger-expression-value', - }, - ], - 'atom-text-editor': [ - {type: 'separator'}, - { - label: 'Debugger', - submenu: [ - { - label: 'Toggle Breakpoint', - command: 'debugger:toggle-breakpoint', - }, - { - label: 'Toggle Breakpoint enabled/disabled', - command: 'debugger:toggle-breakpoint-enabled', - shouldDisplay: event => - this._executeWithEditorPath( - event, - (filePath, line) => - this._service - .getModel() - .getBreakpointAtLine(filePath, line) != null, - ) || false, - }, - { - label: 'Edit Breakpoint...', - command: 'debugger:edit-breakpoint', - shouldDisplay: event => - this._executeWithEditorPath(event, (filePath, line) => { - const bp = this._service - .getModel() - .getBreakpointAtLine(filePath, line); - return bp != null && this._supportsConditionalBreakpoints(); - }) || false, - }, - { - label: 'Add to Watch', - command: 'debugger:add-to-watch', - shouldDisplay: event => { - const textEditor = atom.workspace.getActiveTextEditor(); - if ( - this._service.getDebuggerMode() === DebuggerMode.STOPPED || - textEditor == null - ) { - return false; - } - return ( - textEditor.getSelections().length === 1 && - !textEditor.getSelectedBufferRange().isEmpty() - ); - }, - }, - { - label: 'Run to Location', - command: 'debugger:run-to-location', - shouldDisplay: event => - this._service.getDebuggerMode() === DebuggerMode.PAUSED, - }, - ], - }, - {type: 'separator'}, - ], - }), - this._registerCommandsContextMenuAndOpener(), - ); - } - - _supportsConditionalBreakpoints(): boolean { + } + return ( + textEditor.getSelections().length === 1 && + !textEditor.getSelectedBufferRange().isEmpty()); + + } }, + + { + label: 'Run to Location', + command: 'debugger:run-to-location', + shouldDisplay: event => + this._service.getDebuggerMode() === (_constants || _load_constants()).DebuggerMode.PAUSED }] }, + + + + { type: 'separator' }] }), + + + this._registerCommandsContextMenuAndOpener()); + + } + + _supportsConditionalBreakpoints() { // If currently debugging, return whether or not the current debugger supports this. - const {focusedProcess} = this._service.viewModel; + const { focusedProcess } = this._service.viewModel; if (focusedProcess == null) { // If not currently debugging, return if any of the debuggers that support // the file extension this bp is in support conditions. @@ -368,65 +368,65 @@ class Activation { return true; } else { return Boolean( - focusedProcess.session.capabilities.supportsConditionalBreakpoints, - ); + focusedProcess.session.capabilities.supportsConditionalBreakpoints); + } } - _supportsTerminateThreadsRequest(): boolean { + _supportsTerminateThreadsRequest() { // If currently debugging, return whether or not the current debugger supports this. - const {focusedProcess} = this._service.viewModel; + const { focusedProcess } = this._service.viewModel; if (focusedProcess == null) { return false; } else { return Boolean( - focusedProcess.session.capabilities.supportsTerminateThreadsRequest, - ); + focusedProcess.session.capabilities.supportsTerminateThreadsRequest); + } } - _setProvidersForConnection(connection: NuclideUri): void { - const key = nuclideUri.isRemote(connection) - ? nuclideUri.getHostname(connection) - : 'local'; + _setProvidersForConnection(connection) { + const key = (_nuclideUri || _load_nuclideUri()).default.isRemote(connection) ? + (_nuclideUri || _load_nuclideUri()).default.getHostname(connection) : + 'local'; const availableProviders = this._uiModel.getLaunchAttachProvidersForConnection( - connection, - ); + connection); + this._connectionProviders.set(key, availableProviders); } - async _getSuggestions( - request: atom$AutocompleteRequest, - ): Promise> { - let text = request.editor.getText(); - const lines = text.split('\n'); - const {row} = request.bufferPosition; - // Only keep the lines up to and including the buffer position row. - text = lines.slice(0, row + 1).join('\n'); - const {focusedStackFrame, focusedProcess} = this._service.viewModel; - if (focusedProcess == null || focusedStackFrame == null) { - return []; - } else if ( - !Boolean(focusedProcess.session.capabilities.supportsCompletionsRequest) - ) { - const scopes = await focusedStackFrame.getScopes(); - return scopes.map(scope => ({text: scope.name, type: 'variable'})); - } else { - const completions = await focusedProcess.completions( + _getSuggestions( + request) + {var _this = this;return (0, _asyncToGenerator.default)(function* () { + let text = request.editor.getText(); + const lines = text.split('\n'); + const { row } = request.bufferPosition; + // Only keep the lines up to and including the buffer position row. + text = lines.slice(0, row + 1).join('\n'); + const { focusedStackFrame, focusedProcess } = _this._service.viewModel; + if (focusedProcess == null || focusedStackFrame == null) { + return []; + } else if ( + !Boolean(focusedProcess.session.capabilities.supportsCompletionsRequest)) + { + const scopes = yield focusedStackFrame.getScopes(); + return scopes.map(function (scope) {return { text: scope.name, type: 'variable' };}); + } else { + const completions = yield focusedProcess.completions( focusedStackFrame.frameId, text, request.bufferPosition, - 0, - ); - return completions.map(item => ({ - displayText: item.label, - text: item.text == null ? item.label : item.text, - type: item.type, - })); - } + 0); + + return completions.map(function (item) {return { + displayText: item.label, + text: item.text == null ? item.label : item.text, + type: item.type };}); + + }})(); } - serialize(): SerializedState { + serialize() { const model = this._service.getModel(); const state = { sourceBreakpoints: model.getBreakpoints(), @@ -434,8 +434,8 @@ class Activation { exceptionBreakpoints: model.getExceptionBreakpoints(), watchExpressions: model.getWatchExpressions().map(e => e.name), showDebugger: this._layoutManager.isDebuggerVisible(), - workspaceDocksVisibility: this._layoutManager.getWorkspaceDocksVisibility(), - }; + workspaceDocksVisibility: this._layoutManager.getWorkspaceDocksVisibility() }; + return state; } @@ -443,75 +443,75 @@ class Activation { this._disposables.dispose(); } - _registerCommandsContextMenuAndOpener(): UniversalDisposable { - const disposable = new UniversalDisposable( - atom.workspace.addOpener(uri => { - return this._layoutManager.getModelForDebuggerUri(uri); - }), - () => { - this._layoutManager.hideDebuggerViews(false); - }, - atom.commands.add('atom-workspace', { - 'debugger:show': event => { - const detail = event.detail; - const show = - detail == null || - Boolean(detail.showOnlyIfHidden) === false || - !this._layoutManager.isDebuggerVisible(); - if (show) { - this._layoutManager.showDebuggerViews(); - } - }, - }), - atom.commands.add('atom-workspace', { - 'debugger:hide': () => { - this._layoutManager.hideDebuggerViews(false); - this._service.stopProcess(); - }, - }), - atom.commands.add('atom-workspace', 'debugger:toggle', () => { - if (this._layoutManager.isDebuggerVisible() === true) { - atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'debugger:hide', - ); - } else { - atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'debugger:show', - ); + _registerCommandsContextMenuAndOpener() { + const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default( + atom.workspace.addOpener(uri => { + return this._layoutManager.getModelForDebuggerUri(uri); + }), + () => { + this._layoutManager.hideDebuggerViews(false); + }, + atom.commands.add('atom-workspace', { + 'debugger:show': event => { + const detail = event.detail; + const show = + detail == null || + Boolean(detail.showOnlyIfHidden) === false || + !this._layoutManager.isDebuggerVisible(); + if (show) { + this._layoutManager.showDebuggerViews(); } - }), - this._service.onDidChangeMode(() => - this._layoutManager.debuggerModeChanged(), - ), - atom.commands.add('atom-workspace', { - 'debugger:reset-layout': () => { - this._layoutManager.resetLayout(); - }, - }), - atom.contextMenu.add({ - '.debugger-container': [ - { - label: 'Debugger Views', - submenu: [ - { - label: 'Reset Layout', - command: 'debugger:reset-layout', - }, - ], - }, - ], - }), - ); + } }), + + atom.commands.add('atom-workspace', { + 'debugger:hide': () => { + this._layoutManager.hideDebuggerViews(false); + this._service.stopProcess(); + } }), + + atom.commands.add('atom-workspace', 'debugger:toggle', () => { + if (this._layoutManager.isDebuggerVisible() === true) { + atom.commands.dispatch( + atom.views.getView(atom.workspace), + 'debugger:hide'); + + } else { + atom.commands.dispatch( + atom.views.getView(atom.workspace), + 'debugger:show'); + + } + }), + this._service.onDidChangeMode(() => + this._layoutManager.debuggerModeChanged()), + + atom.commands.add('atom-workspace', { + 'debugger:reset-layout': () => { + this._layoutManager.resetLayout(); + } }), + + atom.contextMenu.add({ + '.debugger-container': [ + { + label: 'Debugger Views', + submenu: [ + { + label: 'Reset Layout', + command: 'debugger:reset-layout' }] }] })); + + + + + + this._layoutManager.registerContextMenus(); return disposable; } _continue() { - const {focusedThread} = this._service.viewModel; + const { focusedThread } = this._service.viewModel; if (focusedThread != null) { - track(AnalyticsEvents.DEBUGGER_STEP_CONTINUE); + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_STEP_CONTINUE); focusedThread.continue(); } } @@ -525,36 +525,36 @@ class Activation { } _stepOver() { - const {focusedThread} = this._service.viewModel; + const { focusedThread } = this._service.viewModel; if (focusedThread != null) { - track(AnalyticsEvents.DEBUGGER_STEP_OVER); + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_STEP_OVER); focusedThread.next(); } } _stepInto() { - const {focusedThread} = this._service.viewModel; + const { focusedThread } = this._service.viewModel; if (focusedThread != null) { - track(AnalyticsEvents.DEBUGGER_STEP_INTO); + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_STEP_INTO); focusedThread.stepIn(); } } _stepOut() { - const {focusedThread} = this._service.viewModel; + const { focusedThread } = this._service.viewModel; if (focusedThread != null) { - track(AnalyticsEvents.DEBUGGER_STEP_OUT); + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_STEP_OUT); focusedThread.stepOut(); } } - _toggleBreakpoint(event: any) { + _toggleBreakpoint(event) { return this._executeWithEditorPath(event, (filePath, lineNumber) => { this._service.toggleSourceBreakpoint(filePath, lineNumber); }); } - _toggleBreakpointEnabled(event: any) { + _toggleBreakpointEnabled(event) { this._executeWithEditorPath(event, (filePath, line) => { const bp = this._service.getModel().getBreakpointAtLine(filePath, line); @@ -564,8 +564,8 @@ class Activation { }); } - _getBreakpointFromEvent(event: any): ?IBreakpoint { - const target: HTMLElement = event.target; + _getBreakpointFromEvent(event) { + const target = event.target; let bp = null; if (target != null && target.dataset != null) { if (target.dataset.bpid != null) { @@ -585,26 +585,26 @@ class Activation { return bp; } - _configureBreakpoint(event: any) { + _configureBreakpoint(event) { const bp = this._getBreakpointFromEvent(event); if (bp != null && this._supportsConditionalBreakpoints()) { // Open the configuration dialog. - const container = new ReactMountRootElement(); - ReactDOM.render( - { - ReactDOM.unmountComponentAtNode(container); - }} - />, - container, - ); + const container = new (_ReactMountRootElement || _load_ReactMountRootElement()).default(); + _reactDom.default.render( + _react.createElement((_BreakpointConfigComponent || _load_BreakpointConfigComponent()).default, { + breakpoint: bp, + service: this._service, + onDismiss: () => { + _reactDom.default.unmountComponentAtNode(container); + } }), + + container); + } } - _terminateThread(event: any) { - const target: HTMLElement = event.target; + _terminateThread(event) { + const target = event.target; if (target.dataset.threadid) { const threadId = parseInt(target.dataset.threadid, 10); if (!Number.isNaN(threadId) && this._supportsTerminateThreadsRequest()) { @@ -613,129 +613,129 @@ class Activation { } } - _executeWithEditorPath( - event: any, - fn: (filePath: string, line: number) => T, - ): ?T { + _executeWithEditorPath( + event, + fn) + { const editor = atom.workspace.getActiveTextEditor(); if (!editor || !editor.getPath()) { return null; } - const line = getLineForEvent(editor, event) + 1; - return fn(nullthrows(editor.getPath()), line); + const line = (0, (_utils || _load_utils()).getLineForEvent)(editor, event) + 1; + return fn((0, (_nullthrows || _load_nullthrows()).default)(editor.getPath()), line); } - _deleteBreakpoint(event: any): void { + _deleteBreakpoint(event) { const breakpoint = this._getBreakpointFromEvent(event); if (breakpoint != null) { this._service.removeBreakpoints(breakpoint.getId()); } } - _deleteAllBreakpoints(): void { + _deleteAllBreakpoints() { this._service.removeBreakpoints(); } - _enableAllBreakpoints(): void { + _enableAllBreakpoints() { this._service.enableOrDisableBreakpoints(true); } - _disableAllBreakpoints(): void { + _disableAllBreakpoints() { this._service.enableOrDisableBreakpoints(false); } _renderConfigDialog( - panel: atom$Panel, - dialogMode: DebuggerConfigAction, - dialogCloser: () => void, - ): void { + panel, + dialogMode, + dialogCloser) + { if (this._selectedDebugConnection == null) { // If no connection is selected yet, default to the local connection. this._selectedDebugConnection = 'local'; - } + }if (!( + + this._selectedDebugConnection != null)) {throw new Error('Invariant violation: "this._selectedDebugConnection != null"');} - invariant(this._selectedDebugConnection != null); - - const options = this._uiModel - .getConnections() - .map(connection => { - const displayName = nuclideUri.isRemote(connection) - ? nuclideUri.getHostname(connection) - : 'localhost'; - return { - value: connection, - label: displayName, - }; - }) - .filter(item => item.value != null && item.value !== '') - .sort((a, b) => a.label.localeCompare(b.label)); + const options = this._uiModel. + getConnections(). + map(connection => { + const displayName = (_nuclideUri || _load_nuclideUri()).default.isRemote(connection) ? + (_nuclideUri || _load_nuclideUri()).default.getHostname(connection) : + 'localhost'; + return { + value: connection, + label: displayName }; + + }). + filter(item => item.value != null && item.value !== ''). + sort((a, b) => a.label.localeCompare(b.label)); // flowlint-next-line sketchy-null-string:off const connection = this._selectedDebugConnection || 'local'; - ReactDOM.render( - { - this._selectedDebugConnection = newValue; - this._renderConfigDialog(panel, dialogMode, dialogCloser); - }} - connection={connection} - connectionOptions={options} - dialogCloser={dialogCloser} - providers={this._connectionProviders} - />, - panel.getItem(), - ); - } - - _showLaunchAttachDialog(dialogMode: DebuggerConfigAction): void { + _reactDom.default.render( + _react.createElement((_DebuggerLaunchAttachUI || _load_DebuggerLaunchAttachUI()).default, { + dialogMode: dialogMode, + connectionChanged: newValue => { + this._selectedDebugConnection = newValue; + this._renderConfigDialog(panel, dialogMode, dialogCloser); + }, + connection: connection, + connectionOptions: options, + dialogCloser: dialogCloser, + providers: this._connectionProviders }), + + panel.getItem()); + + } + + _showLaunchAttachDialog(dialogMode) { if ( - this._visibleLaunchAttachDialogMode != null && - this._visibleLaunchAttachDialogMode !== dialogMode - ) { + this._visibleLaunchAttachDialogMode != null && + this._visibleLaunchAttachDialogMode !== dialogMode) + { // If the dialog is already visible, but isn't the correct mode, close it before // re-opening the correct mode. - invariant(this._lauchAttachDialogCloser != null); + if (!(this._lauchAttachDialogCloser != null)) {throw new Error('Invariant violation: "this._lauchAttachDialogCloser != null"');} this._lauchAttachDialogCloser(); } - const disposables = new UniversalDisposable(); + const disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); const hostEl = document.createElement('div'); const pane = atom.workspace.addModalPanel({ - item: hostEl, - }); + item: hostEl }); - const parentEl: HTMLElement = (hostEl.parentElement: any); + + const parentEl = hostEl.parentElement; parentEl.style.maxWidth = '100em'; // Function callback that closes the dialog and frees all of its resources. this._renderConfigDialog(pane, dialogMode, () => disposables.dispose()); this._lauchAttachDialogCloser = () => disposables.dispose(); disposables.add( - pane.onDidChangeVisible(visible => { - if (!visible) { - disposables.dispose(); - } - }), - ); + pane.onDidChangeVisible(visible => { + if (!visible) { + disposables.dispose(); + } + })); + disposables.add(() => { this._disposables.remove(disposables); this._visibleLaunchAttachDialogMode = null; this._lauchAttachDialogCloser = null; - track(AnalyticsEvents.DEBUGGER_TOGGLE_ATTACH_DIALOG, { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_TOGGLE_ATTACH_DIALOG, { visible: false, - dialogMode, - }); - ReactDOM.unmountComponentAtNode(hostEl); + dialogMode }); + + _reactDom.default.unmountComponentAtNode(hostEl); pane.destroy(); }); - track(AnalyticsEvents.DEBUGGER_TOGGLE_ATTACH_DIALOG, { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_TOGGLE_ATTACH_DIALOG, { visible: true, - dialogMode, - }); + dialogMode }); + this._visibleLaunchAttachDialogMode = dialogMode; this._disposables.add(disposables); } @@ -746,11 +746,11 @@ class Activation { return; } const selectedText = editor.getTextInBufferRange( - trimRange(editor, editor.getSelectedBufferRange()), - ); - const expr = wordAtPosition(editor, editor.getCursorBufferPosition()); + (0, (_range || _load_range()).trimRange)(editor, editor.getSelectedBufferRange())); - const watchExpression = selectedText || (expr && expr.wordMatch[0]); + const expr = (0, (_range || _load_range()).wordAtPosition)(editor, editor.getCursorBufferPosition()); + + const watchExpression = selectedText || expr && expr.wordMatch[0]; if (watchExpression != null && watchExpression.length > 0) { this._service.addWatchExpression(watchExpression); } @@ -762,22 +762,22 @@ class Activation { }); } - _copyDebuggerExpressionValue(event: Event) { - const clickedElement: HTMLElement = (event.target: any); + _copyDebuggerExpressionValue(event) { + const clickedElement = event.target; const copyElement = clickedElement.closest('.nuclide-ui-lazy-nested-value'); if (copyElement != null) { atom.clipboard.write(copyElement.textContent); } } - _copyDebuggerCallstack(event: Event) { - const {focusedThread} = this._service.viewModel; + _copyDebuggerCallstack(event) { + const { focusedThread } = this._service.viewModel; if (focusedThread != null) { let callstackText = ''; focusedThread.getCallStack().forEach((item, i) => { - const path = nuclideUri.basename(item.source.uri); + const path = (_nuclideUri || _load_nuclideUri()).default.basename(item.source.uri); callstackText += `${i}\t${item.name}\t${path}:${item.range.start.row}${ - os.EOL + _os.default.EOL }`; }); @@ -785,17 +785,17 @@ class Activation { } } - consumeCurrentWorkingDirectory(cwdApi: nuclide$CwdApi): IDisposable { + consumeCurrentWorkingDirectory(cwdApi) { const updateSelectedConnection = directory => { this._selectedDebugConnection = directory; if (this._selectedDebugConnection != null) { const conn = this._selectedDebugConnection; - if (nuclideUri.isRemote(conn)) { + if ((_nuclideUri || _load_nuclideUri()).default.isRemote(conn)) { // Use root instead of current directory as launch point for debugger. - this._selectedDebugConnection = nuclideUri.createRemoteUri( - nuclideUri.getHostname(conn), - '/', - ); + this._selectedDebugConnection = (_nuclideUri || _load_nuclideUri()).default.createRemoteUri( + (_nuclideUri || _load_nuclideUri()).default.getHostname(conn), + '/'); + } else { // Use null instead of local path to use local debugger downstream. this._selectedDebugConnection = null; @@ -804,67 +804,67 @@ class Activation { }; const boundUpdateSelectedColumn = updateSelectedConnection.bind(this); const disposable = cwdApi.observeCwd(directory => - boundUpdateSelectedColumn(directory), - ); + boundUpdateSelectedColumn(directory)); + this._disposables.add(disposable); - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { disposable.dispose(); this._disposables.remove(disposable); }); } - createAutocompleteProvider(): atom$AutocompleteProvider { + createAutocompleteProvider() { return { labels: ['nuclide-console'], selector: '*', filterSuggestions: true, - getSuggestions: this._getSuggestions.bind(this), - }; + getSuggestions: this._getSuggestions.bind(this) }; + } - consumeConsole(createConsole: ConsoleService): IDisposable { - return setConsoleService(createConsole); + consumeConsole(createConsole) { + return (0, (_AtomServiceContainer || _load_AtomServiceContainer()).setConsoleService)(createConsole); } - consumeTerminal(terminalApi: TerminalApi): IDisposable { - return setTerminalService(terminalApi); + consumeTerminal(terminalApi) { + return (0, (_AtomServiceContainer || _load_AtomServiceContainer()).setTerminalService)(terminalApi); } - consumeRpcService(rpcService: nuclide$RpcService): IDisposable { - return setRpcService(rpcService); + consumeRpcService(rpcService) { + return (0, (_AtomServiceContainer || _load_AtomServiceContainer()).setRpcService)(rpcService); } consumeRegisterExecutor( - registerExecutor: RegisterExecutorFunction, - ): IDisposable { - return setConsoleRegisterExecutor(registerExecutor); + registerExecutor) + { + return (0, (_AtomServiceContainer || _load_AtomServiceContainer()).setConsoleRegisterExecutor)(registerExecutor); } - consumeDebuggerProvider(provider: NuclideDebuggerProvider): IDisposable { + consumeDebuggerProvider(provider) { this._uiModel.addDebuggerProvider(provider); - return new UniversalDisposable(() => { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { this._uiModel.removeDebuggerProvider(provider); }); } consumeDebuggerConfigurationProvider( - provider: DebuggerConfigurationProvider, - ): IDisposable { - return addDebugConfigurationProvider(provider); + provider) + { + return (0, (_AtomServiceContainer || _load_AtomServiceContainer()).addDebugConfigurationProvider)(provider); } - consumeToolBar(getToolBar: toolbar$GetToolbar): IDisposable { + consumeToolBar(getToolBar) { const toolBar = getToolBar('debugger'); toolBar.addButton( - makeToolbarButtonSpec({ - iconset: 'icon-nuclicon', - icon: 'debugger', - callback: 'debugger:show-attach-dialog', - tooltip: 'Attach Debugger', - priority: 500, - }), - ).element; - const disposable = new UniversalDisposable(() => { + (0, (_ToolbarUtils || _load_ToolbarUtils()).makeToolbarButtonSpec)({ + iconset: 'icon-nuclicon', + icon: 'debugger', + callback: 'debugger:show-attach-dialog', + tooltip: 'Attach Debugger', + priority: 500 })). + + element; + const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(() => { toolBar.removeItems(); }); this._disposables.add(disposable); @@ -872,52 +872,52 @@ class Activation { } consumeNotifications( - raiseNativeNotification: ( - title: string, - body: string, - timeout: number, - raiseIfAtomHasFocus: boolean, - ) => ?IDisposable, - ): void { - setNotificationService(raiseNativeNotification); + raiseNativeNotification) + + + + + + { + (0, (_AtomServiceContainer || _load_AtomServiceContainer()).setNotificationService)(raiseNativeNotification); } - provideRemoteControlService(): RemoteControlService { - return new RemoteControlService(this._service); + provideRemoteControlService() { + return new (_RemoteControlService || _load_RemoteControlService()).default(this._service); } - consumeDatatipService(service: DatatipService): IDisposable { - const disposable = new UniversalDisposable( - service.addProvider(this._createDatatipProvider()), - setDatatipService(service), - ); + consumeDatatipService(service) { + const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default( + service.addProvider(this._createDatatipProvider()), + (0, (_AtomServiceContainer || _load_AtomServiceContainer()).setDatatipService)(service)); + this._disposables.add(disposable); return disposable; } - _createDatatipProvider(): DatatipProvider { + _createDatatipProvider() { return { // Eligibility is determined online, based on registered EvaluationExpression providers. providerName: DATATIP_PACKAGE_NAME, priority: 1, - datatip: (editor: TextEditor, position: atom$Point) => { - return debuggerDatatip(this._service, editor, position); - }, - }; - } -} + datatip: (editor, position) => { + return (0, (_DebuggerDatatip || _load_DebuggerDatatip()).debuggerDatatip)(this._service, editor, position); + } }; + + }} + -function createDebuggerView(model: mixed): ?HTMLElement { +function createDebuggerView(model) { let view = null; if ( - model instanceof DebuggerPaneViewModel || - model instanceof DebuggerPaneContainerViewModel - ) { + model instanceof (_DebuggerPaneViewModel || _load_DebuggerPaneViewModel()).default || + model instanceof (_DebuggerPaneContainerViewModel || _load_DebuggerPaneContainerViewModel()).default) + { view = model.createView(); } if (view != null) { - const elem = renderReactRoot(view); + const elem = (0, (_renderReactRoot || _load_renderReactRoot()).renderReactRoot)(view); elem.className = 'debugger-container'; return elem; } @@ -925,4 +925,4 @@ function createDebuggerView(model: mixed): ?HTMLElement { return null; } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/types.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/types.js index 91e5ec51..ba7762dd 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/types.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/types.js @@ -1,492 +1,44 @@ -/** - * 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 - * @format - */ - -/** - * The following interfaces models a debug service and data model layer built on top of - * VSCode debugger protocol and were modeled after VSCode's debugger implementation - * in https://github.com/Microsoft/vscode/tree/master/src/vs/workbench/parts/debug - -MIT License - -Copyright (c) 2015 - present Microsoft Corporation - -All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -import type {Observable} from 'rxjs'; -import * as DebugProtocol from 'vscode-debugprotocol'; -import type {IProcessConfig} from 'nuclide-debugger-common'; - -export interface ITreeElement { - getId(): string; -} - -export interface ISource { - available: boolean; - +name: ?string; - +uri: string; - +origin: ?string; - +presentationHint: ?SourcePresentationHint; - +raw: DebugProtocol.Source; - +reference: ?number; - +inMemory: boolean; - openInEditor(): Promise; -} - -export type SourcePresentationHint = 'normal' | 'emphasize' | 'deemphasize'; - -export interface IExpressionContainer extends ITreeElement { - hasChildren(): boolean; - getChildren(): Promise>; -} - -export interface IExpression extends IExpressionContainer { - available: boolean; - name: string; - getValue(): string; - +type: ?string; - toString(): string; -} - -export type ContextType = 'hover' | 'watch' | 'repl'; - -export interface IEvaluatableExpression extends IExpression { - evaluate( - process: ?IProcess, - stackFrame: ?IStackFrame, - context: ContextType, - ): Promise; -} - -export interface IVariable extends IExpression { - setVariable(newValue: string): Promise; -} - -export interface ISession { - stackTrace( - args: DebugProtocol.StackTraceArguments, - ): Promise; - exceptionInfo( - args: DebugProtocol.ExceptionInfoArguments, - ): Promise; - scopes( - args: DebugProtocol.ScopesArguments, - ): Promise; - variables( - args: DebugProtocol.VariablesArguments, - ): Promise; - evaluate( - args: DebugProtocol.EvaluateArguments, - ): Promise; - capabilities: DebugProtocol.Capabilities; - disconnect(restart?: boolean, force?: boolean): Promise; - custom(request: string, args: any): Promise; - observeInitializeEvents(): Observable; - observeCustomEvents(): Observable; - observeStopEvents(): Observable; - restartFrame( - args: DebugProtocol.RestartFrameArguments, - threadId: number, - ): Promise; - next(args: DebugProtocol.NextArguments): Promise; - stepIn( - args: DebugProtocol.StepInArguments, - ): Promise; - stepOut( - args: DebugProtocol.StepOutArguments, - ): Promise; - continue( - args: DebugProtocol.ContinueArguments, - ): Promise; - pause( - args: DebugProtocol.PauseArguments, - ): Promise; - stepBack( - args: DebugProtocol.StepBackArguments, - ): Promise; - reverseContinue( - args: DebugProtocol.ReverseContinueArguments, - ): Promise; - completions( - args: DebugProtocol.CompletionsArguments, - ): Promise; - setVariable( - args: DebugProtocol.SetVariableArguments, - ): Promise; - source( - args: DebugProtocol.SourceArguments, - ): Promise; -} - -export interface IThread extends ITreeElement { - /** - * Process the thread belongs to - */ - +process: IProcess; - - /** - * Id of the thread generated by the debug adapter backend. - */ - +threadId: number; - - /** - * Name of the thread. - */ - name: string; - - /** - * Information about the current thread stop event. Null if thread is not stopped. - */ - stoppedDetails: ?IRawStoppedDetails; - - /** - * Information about the exception if an 'exception' stopped event raised and DA supports the 'exceptionInfo' request, otherwise null. - */ - exceptionInfo(): Promise; - - /** - * Gets the already-fetched callstack from the debug adapter. - */ - getCallStack(): IStackFrame[]; - - /** - * Invalidates the callstack cache. - */ - clearCallStack(): void; - - /** - * Fetches more callstack items on user demand - */ - fetchCallStack(levels?: number): Promise; - - /** - * Indicates whether this thread is stopped. The callstack for stopped - * threads can be retrieved from the debug adapter. - */ - stopped: boolean; - - next(): Promise; - stepIn(): Promise; - stepOut(): Promise; - stepBack(): Promise; - continue(): Promise; - pause(): Promise; - reverseContinue(): Promise; -} - -export interface IScope extends IExpressionContainer { - +name: string; - +expensive: boolean; - +range: ?atom$Range; -} - -export interface IProcess extends ITreeElement { - +configuration: IProcessConfig; - +session: ISession & ITreeElement; - +sources: Map; - getThread(threadId: number): ?IThread; - getAllThreads(): IThread[]; - getSource(raw: ?DebugProtocol.Source): ISource; - completions( - frameId: number, - text: string, - position: atom$Point, - overwriteBefore: number, - ): Promise>; -} - -export interface IEnableable extends ITreeElement { - enabled: boolean; -} - -export interface IRawBreakpoint { - line: number; - column?: number; - enabled?: boolean; - condition?: string; - hitCondition?: string; -} - -export interface IExceptionBreakpoint extends IEnableable { - +filter: string; - +label: string; -} - -export type IExceptionInfo = { - id: ?string, - description: ?string, - breakMode: ?string, - details: ?DebugProtocol.ExceptionDetails, -}; - -export interface IViewModel { - /** - * Returns the focused debug process or null if no process is stopped. - */ - +focusedProcess: ?IProcess; - - /** - * Returns the focused thread or null if no thread is stopped. - */ - +focusedThread: ?IThread; - - /** - * Returns the focused stack frame or null if there are no stack frames. - */ - +focusedStackFrame: ?IStackFrame; - isMultiProcessView(): boolean; - - onDidFocusProcess(callback: (process: ?IProcess) => mixed): IDisposable; - onDidFocusStackFrame( - callback: (data: {stackFrame: ?IStackFrame, explicit: boolean}) => mixed, - ): IDisposable; - onDidChangeExpressionContext( - callback: (data: {stackFrame: ?IStackFrame, explicit: boolean}) => mixed, - ): IDisposable; -} - -export interface IModel extends ITreeElement { - getProcesses(): IProcess[]; - getBreakpoints(): IBreakpoint[]; - getBreakpointAtLine(uri: string, line: number): ?IBreakpoint; - getBreakpointById(id: string): ?IBreakpoint; - - areBreakpointsActivated(): boolean; - getFunctionBreakpoints(): IFunctionBreakpoint[]; - getExceptionBreakpoints(): IExceptionBreakpoint[]; - getWatchExpressions(): IEvaluatableExpression[]; - fetchCallStack(thread: IThread): Promise; - - onDidChangeBreakpoints( - callback: (event: ?IBreakpointsChangeEvent) => mixed, - ): IDisposable; - onDidChangeCallStack(callback: () => mixed): IDisposable; - onDidChangeWatchExpressions( - callback: (expression: ?IExpression) => mixed, - ): IDisposable; -} - -export interface IBreakpointsChangeEvent { - added?: (IBreakpoint | IFunctionBreakpoint)[]; - removed?: (IBreakpoint | IFunctionBreakpoint)[]; - changed?: (IBreakpoint | IFunctionBreakpoint)[]; -} - -/* Debugger mode */ -export type DebuggerModeType = - | 'starting' - | 'running' - | 'paused' - | 'stopping' - | 'stopped'; - -export interface IDebugService { - +viewModel: IViewModel; - getDebuggerMode(): DebuggerModeType; - - onDidChangeMode(callback: (mode: DebuggerModeType) => mixed): IDisposable; - onDidCustomEvent( - callback: (event: DebugProtocol.DebugEvent) => mixed, - ): IDisposable; - - /** - * Sets the focused stack frame and evaluates all expressions against the newly focused stack frame, - */ - focusStackFrame( - stackFrame: ?IStackFrame, - thread: ?IThread, - process: ?IProcess, - explicit?: boolean, - ): void; - - /** - * Adds new breakpoints to the model for the file specified with the uri. Notifies debug adapter of breakpoint changes. - */ - addBreakpoints(uri: string, rawBreakpoints: IRawBreakpoint[]): Promise; - - /** - * Updates the breakpoints. - */ - updateBreakpoints( - uri: string, - data: {[id: string]: DebugProtocol.Breakpoint}, - ): void; - - /** - * Enables or disables all breakpoints. If breakpoint is passed only enables or disables the passed breakpoint. - * Notifies debug adapter of breakpoint changes. - */ - enableOrDisableBreakpoints( - enable: boolean, - breakpoint?: IEnableable, - ): Promise; - - toggleSourceBreakpoint(uri: string, line: number): Promise; - - /** - * Sets the global activated property for all breakpoints. - * Notifies debug adapter of breakpoint changes. - */ - setBreakpointsActivated(activated: boolean): Promise; - - /** - * Removes all breakpoints. If id is passed only removes the breakpoint associated with that id. - * Notifies debug adapter of breakpoint changes. - */ - removeBreakpoints(id?: string): Promise; - - /** - * Adds a new no name function breakpoint. The function breakpoint should be renamed once user enters the name. - */ - addFunctionBreakpoint(): void; - - /** - * Renames an already existing function breakpoint. - * Notifies debug adapter of breakpoint changes. - */ - renameFunctionBreakpoint(id: string, newFunctionName: string): Promise; - - /** - * Removes all function breakpoints. If id is passed only removes the function breakpoint with the passed id. - * Notifies debug adapter of breakpoint changes. - */ - removeFunctionBreakpoints(id?: string): Promise; - - /** - * Adds a new watch expression and evaluates it against the debug adapter. - */ - addWatchExpression(name: string): void; - - /** - * Creates an expression to be evaluated. - */ - createExpression(rawExpression: string): IEvaluatableExpression; - - /** - * Renames a watch expression and evaluates it against the debug adapter. - */ - renameWatchExpression(id: string, newName: string): void; - - /** - * Removes all watch expressions. If id is passed only removes the watch expression with the passed id. - */ - removeWatchExpressions(id?: string): void; - - /** - * Starts debugging. If the configOrName is not passed uses the selected configuration in the debug dropdown. - * Also saves all files, manages if compounds are present in the configuration - * and resolveds configurations via DebugConfigurationProviders. - */ - startDebugging(config: IProcessConfig): Promise; - - /** - * Restarts a process or creates a new one if there is no active session. - */ - restartProcess(): Promise; - - /** - * Stops the process. If the process does not exist then stops all processes. - */ - stopProcess(): Promise; - - /** - * Gets the current debug model. - */ - getModel(): IModel; -} - -export interface IStackFrame extends ITreeElement { - thread: IThread; - name: string; - presentationHint: ?string; - frameId: number; - range: atom$Range; - source: ISource; - getScopes(): Promise; - getMostSpecificScopes(range: atom$Range): Promise; - restart(): Promise; - toString(): string; - openInEditor(): Promise; -} - -export interface IBreakpoint extends IEnableable { - uri: string; - line: number; - endLine: ?number; - column: number; - endColumn: ?number; - condition: ?string; - hitCondition: ?string; - verified: boolean; - idFromAdapter: ?number; - message: ?string; - adapterData?: any; -} - -export interface IFunctionBreakpoint extends IEnableable { - name: string; - verified: boolean; - idFromAdapter: ?number; - condition?: ?string; - hitCondition?: ?string; -} - -export type IRawStopppedUpdate = { - sessionId: string, - threadId: ?number, - stoppedDetails: IRawStoppedDetails, -}; - -export type IRawThreadUpdate = { - sessionId: string, - thread: DebugProtocol.Thread, -}; - -export type IRawModelUpdate = IRawStopppedUpdate | IRawThreadUpdate; - -export interface IRawStoppedDetails { - reason?: string; - preserveFocusHint?: boolean; - description?: string; - threadId?: number; - text?: string; - totalFrames?: number; - allThreadsStopped?: boolean; - framesErrorMessage?: string; -} - -export type SerializedState = { - sourceBreakpoints: ?Array, - functionBreakpoints: ?Array, - exceptionBreakpoints: ?Array, - watchExpressions: ?Array, - showDebugger: boolean, - workspaceDocksVisibility: Array, -}; +'use strict';var _vscodeDebugprotocol; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +function _load_vscodeDebugprotocol() {return _vscodeDebugprotocol = _interopRequireWildcard(require('vscode-debugprotocol'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/BreakpointConfigComponent.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/BreakpointConfigComponent.js index 00ea6ca5..80eff921 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/BreakpointConfigComponent.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/BreakpointConfigComponent.js @@ -1,182 +1,191 @@ -/** - * 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 - * @format - */ - -import type {IBreakpoint, IRawBreakpoint, IDebugService} from '../types'; - -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import * as React from 'react'; -import {Button, ButtonTypes} from 'nuclide-commons-ui/Button'; -import {ButtonGroup} from 'nuclide-commons-ui/ButtonGroup'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import nullthrows from 'nullthrows'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Checkbox} from 'nuclide-commons-ui/Checkbox'; -import {Modal} from 'nuclide-commons-ui/Modal'; -import {Observable} from 'rxjs'; -import {track} from 'nuclide-commons/analytics'; -import {AnalyticsEvents} from '../constants'; - -type PropsType = { - onDismiss: () => void, - breakpoint: IBreakpoint, - service: IDebugService, -}; - -type StateType = { - bpId: string, -}; - -export default class BreakpointConfigComponent extends React.Component< - PropsType, - StateType, -> { - _condition: ?AtomInput; - props: PropsType; - state: StateType; - _disposables: UniversalDisposable; - - constructor(props: PropsType) { +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _AtomInput; + + + + + + + + + + + + + +function _load_AtomInput() {return _AtomInput = require('nuclide-commons-ui/AtomInput');} +var _react = _interopRequireWildcard(require('react'));var _Button; +function _load_Button() {return _Button = require('nuclide-commons-ui/Button');}var _ButtonGroup; +function _load_ButtonGroup() {return _ButtonGroup = require('nuclide-commons-ui/ButtonGroup');}var _nuclideUri; +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));}var _nullthrows; +function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _Checkbox; +function _load_Checkbox() {return _Checkbox = require('nuclide-commons-ui/Checkbox');}var _Modal; +function _load_Modal() {return _Modal = require('nuclide-commons-ui/Modal');} +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _analytics; +function _load_analytics() {return _analytics = require('nuclide-commons/analytics');}var _constants; +function _load_constants() {return _constants = require('../constants');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + + + + + + + + + + + +class BreakpointConfigComponent extends _react.Component + + +{ + + + + + + constructor(props) { super(props); - this._disposables = new UniversalDisposable(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this.state = { - bpId: this.props.breakpoint.getId(), - }; + bpId: this.props.breakpoint.getId() }; + const model = this.props.service.getModel(); this._disposables.add( - model.onDidChangeBreakpoints(() => { - const breakpoint = model - .getBreakpoints() - .filter(bp => bp.getId() === this.state.bpId); - if (breakpoint == null) { - // Breakpoint no longer exists. - this.props.onDismiss(); - } - this.forceUpdate(); - }), - ); + model.onDidChangeBreakpoints(() => { + const breakpoint = model. + getBreakpoints(). + filter(bp => bp.getId() === this.state.bpId); + if (breakpoint == null) { + // Breakpoint no longer exists. + this.props.onDismiss(); + } + this.forceUpdate(); + })); + } - componentDidMount(): void { - track(AnalyticsEvents.DEBUGGER_BREAKPOINT_CONFIG_UI_SHOW, { - fileExtension: nuclideUri.extname(this.props.breakpoint.uri), - }); + componentDidMount() { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_BREAKPOINT_CONFIG_UI_SHOW, { + fileExtension: (_nuclideUri || _load_nuclideUri()).default.extname(this.props.breakpoint.uri) }); + this._disposables.add( - atom.commands.add('atom-workspace', 'core:cancel', this.props.onDismiss), - atom.commands.add( - 'atom-workspace', - 'core:confirm', - this._updateBreakpoint.bind(this), - ), - Observable.timer(100).subscribe(() => { - if (this._condition != null) { - this._condition.focus(); - } - }), - ); + atom.commands.add('atom-workspace', 'core:cancel', this.props.onDismiss), + atom.commands.add( + 'atom-workspace', + 'core:confirm', + this._updateBreakpoint.bind(this)), + + _rxjsBundlesRxMinJs.Observable.timer(100).subscribe(() => { + if (this._condition != null) { + this._condition.focus(); + } + })); + } - componentWillUnmount(): void { + componentWillUnmount() { this._disposables.dispose(); } - async _updateBreakpoint(): Promise { - const {breakpoint, service} = this.props; - const condition = nullthrows(this._condition) - .getText() - .trim(); - if (condition === (breakpoint.condition || '')) { - this.props.onDismiss(); - return; - } - - await service.removeBreakpoints(breakpoint.getId()); - - const bp: IRawBreakpoint = { - line: breakpoint.line, - column: breakpoint.column, - enabled: breakpoint.enabled, - }; - if (condition !== '') { - bp.condition = condition; - } - - await service.addBreakpoints(breakpoint.uri, [bp]); - track(AnalyticsEvents.DEBUGGER_BREAKPOINT_UPDATE_CONDITION, { - path: breakpoint.uri, - line: breakpoint.line, - condition, - fileExtension: nuclideUri.extname(breakpoint.uri), - }); - this.props.onDismiss(); + _updateBreakpoint() {var _this = this;return (0, _asyncToGenerator.default)(function* () { + const { breakpoint, service } = _this.props; + const condition = (0, (_nullthrows || _load_nullthrows()).default)(_this._condition). + getText(). + trim(); + if (condition === (breakpoint.condition || '')) { + _this.props.onDismiss(); + return; + } + + yield service.removeBreakpoints(breakpoint.getId()); + + const bp = { + line: breakpoint.line, + column: breakpoint.column, + enabled: breakpoint.enabled }; + + if (condition !== '') { + bp.condition = condition; + } + + yield service.addBreakpoints(breakpoint.uri, [bp]); + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_BREAKPOINT_UPDATE_CONDITION, { + path: breakpoint.uri, + line: breakpoint.line, + condition, + fileExtension: (_nuclideUri || _load_nuclideUri()).default.extname(breakpoint.uri) }); + + _this.props.onDismiss();})(); } - render(): React.Node { + render() { return ( - -
-

Edit breakpoint

-
- -
-
- { - track(AnalyticsEvents.DEBUGGER_BREAKPOINT_TOGGLE_ENABLED, { - enabled: isChecked, - }); + _react.createElement((_Modal || _load_Modal()).Modal, { onDismiss: this.props.onDismiss }, + _react.createElement('div', { className: 'padded debugger-bp-dialog' }, + _react.createElement('h1', { className: 'debugger-bp-config-header' }, 'Edit breakpoint'), + _react.createElement('div', { className: 'block' }, + _react.createElement('label', null, 'Breakpoint at ', + (_nuclideUri || _load_nuclideUri()).default.basename(this.props.breakpoint.uri), ':', + + this.props.breakpoint.endLine != null ? + this.props.breakpoint.endLine : + this.props.breakpoint.line)), + + + _react.createElement('div', { className: 'block' }, + _react.createElement((_Checkbox || _load_Checkbox()).Checkbox, { + onChange: isChecked => { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_BREAKPOINT_TOGGLE_ENABLED, { + enabled: isChecked }); + this.props.service.enableOrDisableBreakpoints( - isChecked, - this.props.breakpoint, - ); - }} - checked={this.props.breakpoint.enabled} - label="Enable breakpoint" - /> -
-
- { + isChecked, + this.props.breakpoint); + + }, + checked: this.props.breakpoint.enabled, + label: 'Enable breakpoint' })), + + + _react.createElement('div', { className: 'block' }, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + placeholderText: 'Breakpoint hit condition...', + value: this.props.breakpoint.condition || '', + size: 'sm', + ref: input => { this._condition = input; - }} - autofocus={true} - /> -
- -
- - - - -
-
-
- ); - } -} + }, + autofocus: true })), + + + _react.createElement('label', null, 'This expression will be evaluated each time the corresponding line is hit, but the debugger will only break execution if the expression evaluates to true.'), + + + + + _react.createElement('div', { className: 'debugger-bp-config-actions' }, + _react.createElement((_ButtonGroup || _load_ButtonGroup()).ButtonGroup, null, + _react.createElement((_Button || _load_Button()).Button, { onClick: this.props.onDismiss }, 'Cancel'), + _react.createElement((_Button || _load_Button()).Button, { + buttonType: (_Button || _load_Button()).ButtonTypes.PRIMARY, + onClick: this._updateBreakpoint.bind(this) }, 'Update')))))); + + + + + + + + }}exports.default = BreakpointConfigComponent; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/BreakpointListComponent.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/BreakpointListComponent.js index 469c574a..53f38024 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/BreakpointListComponent.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/BreakpointListComponent.js @@ -1,267 +1,276 @@ -/** - * 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 - * @format - */ - -import type {IBreakpoint, IDebugService, IExceptionBreakpoint} from '../types'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import invariant from 'assert'; -import * as React from 'react'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {Checkbox} from 'nuclide-commons-ui/Checkbox'; -import {track} from 'nuclide-commons/analytics'; -import {ListView, ListViewItem} from 'nuclide-commons-ui/ListView'; -import classnames from 'classnames'; -import {Icon} from 'nuclide-commons-ui/Icon'; -import {AnalyticsEvents} from '../constants'; -import {openSourceLocation} from '../utils'; - -type Props = {| - service: IDebugService, -|}; - -type State = { - supportsConditionalBreakpoints: boolean, - breakpoints: IBreakpoint[], - exceptionBreakpoints: IExceptionBreakpoint[], -}; - -export default class BreakpointListComponent extends React.Component< - Props, - State, -> { - _disposables: UniversalDisposable; - - constructor(props: Props) { - super(props); - this.state = this._computeState(); - } - - _computeState(): State { - const {service} = this.props; - const {focusedProcess} = service.viewModel; - const model = service.getModel(); - return { - supportsConditionalBreakpoints: - focusedProcess != null && - Boolean( - focusedProcess.session.capabilities.supportsConditionalBreakpoints, - ), - breakpoints: model.getBreakpoints(), - exceptionBreakpoints: model.getExceptionBreakpoints(), - }; - } - - componentDidMount(): void { - const model = this.props.service.getModel(); - this._disposables = new UniversalDisposable( - model.onDidChangeBreakpoints(() => { - this.setState(this._computeState()); - }), - ); - } - - componentWillUnmount(): void { - if (this._disposables != null) { - this._disposables.dispose(); - } - } - - _handleBreakpointEnabledChange = ( - breakpoint: IBreakpoint, - enabled: boolean, - ): void => { - this.props.service.enableOrDisableBreakpoints(enabled, breakpoint); - }; - - _handleBreakpointClick = ( - breakpointIndex: number, - breakpoint: ?IBreakpoint, - ): void => { - invariant(breakpoint != null); - const {uri, line} = breakpoint; - // Debugger model is 1-based while Atom UI is zero-based. - openSourceLocation(uri, line - 1); - }; - - render(): React.Node { +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _UniversalDisposable; + + + + + + + + + + + + + +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));} + +var _react = _interopRequireWildcard(require('react'));var _nuclideUri; +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));}var _Checkbox; +function _load_Checkbox() {return _Checkbox = require('nuclide-commons-ui/Checkbox');}var _analytics; +function _load_analytics() {return _analytics = require('nuclide-commons/analytics');}var _ListView; +function _load_ListView() {return _ListView = require('nuclide-commons-ui/ListView');}var _classnames; +function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));}var _Icon; +function _load_Icon() {return _Icon = require('nuclide-commons-ui/Icon');}var _constants; +function _load_constants() {return _constants = require('../constants');}var _utils; +function _load_utils() {return _utils = require('../utils');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + + + + + + + + + + + +class BreakpointListComponent extends _react.Component + + +{ + + + constructor(props) { + super(props);this. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _handleBreakpointEnabledChange = ( + breakpoint, + enabled) => + { + this.props.service.enableOrDisableBreakpoints(enabled, breakpoint); + };this. + + _handleBreakpointClick = ( + breakpointIndex, + breakpoint) => + {if (!( + breakpoint != null)) {throw new Error('Invariant violation: "breakpoint != null"');} + const { uri, line } = breakpoint; + // Debugger model is 1-based while Atom UI is zero-based. + (0, (_utils || _load_utils()).openSourceLocation)(uri, line - 1); + };this.state = this._computeState();}_computeState() {const { service } = this.props;const { focusedProcess } = service.viewModel;const model = service.getModel();return { supportsConditionalBreakpoints: focusedProcess != null && Boolean(focusedProcess.session.capabilities.supportsConditionalBreakpoints), breakpoints: model.getBreakpoints(), exceptionBreakpoints: model.getExceptionBreakpoints() };}componentDidMount() {const model = this.props.service.getModel();this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(model.onDidChangeBreakpoints(() => {this.setState(this._computeState());}));}componentWillUnmount() {if (this._disposables != null) {this._disposables.dispose();}} + + render() { const { breakpoints, exceptionBreakpoints, - supportsConditionalBreakpoints, - } = this.state; - const {service} = this.props; - const items = breakpoints - .sort((breakpointA, breakpointB) => { - const fileA = nuclideUri.basename(breakpointA.uri); - const fileB = nuclideUri.basename(breakpointB.uri); - if (fileA !== fileB) { - return fileA.localeCompare(fileB); - } - - const lineA = - breakpointA.endLine != null ? breakpointA.endLine : breakpointA.line; - const lineB = - breakpointB.endLine != null ? breakpointB.endLine : breakpointB.line; - return lineA - lineB; - }) - .map((breakpoint, i) => { - const basename = nuclideUri.basename(breakpoint.uri); - const {line, endLine, enabled, verified, uri: path} = breakpoint; - const dataLine = - endLine != null && !Number.isNaN(endLine) ? endLine : line; - const bpId = breakpoint.getId(); - const label = `${basename}:${dataLine}`; - const title = !enabled - ? 'Disabled breakpoint' - : !verified - ? 'Unresolved Breakpoint' - : `Breakpoint at ${label} (resolved)`; - - const conditionElement = - supportsConditionalBreakpoints && breakpoint.condition != null ? ( -
{ - atom.commands.dispatch( + supportsConditionalBreakpoints } = + this.state; + const { service } = this.props; + const items = breakpoints. + sort((breakpointA, breakpointB) => { + const fileA = (_nuclideUri || _load_nuclideUri()).default.basename(breakpointA.uri); + const fileB = (_nuclideUri || _load_nuclideUri()).default.basename(breakpointB.uri); + if (fileA !== fileB) { + return fileA.localeCompare(fileB); + } + + const lineA = + breakpointA.endLine != null ? breakpointA.endLine : breakpointA.line; + const lineB = + breakpointB.endLine != null ? breakpointB.endLine : breakpointB.line; + return lineA - lineB; + }). + map((breakpoint, i) => { + const basename = (_nuclideUri || _load_nuclideUri()).default.basename(breakpoint.uri); + const { line, endLine, enabled, verified, uri: path } = breakpoint; + const dataLine = + endLine != null && !Number.isNaN(endLine) ? endLine : line; + const bpId = breakpoint.getId(); + const label = `${basename}:${dataLine}`; + const title = !enabled ? + 'Disabled breakpoint' : + !verified ? + 'Unresolved Breakpoint' : + `Breakpoint at ${label} (resolved)`; + + const conditionElement = + supportsConditionalBreakpoints && breakpoint.condition != null ? + _react.createElement('div', { + className: 'debugger-breakpoint-condition', + title: `Breakpoint condition: ${breakpoint.condition}`, + 'data-path': path, + 'data-line': line, + 'data-bpid': bpId, + onClick: event => { + atom.commands.dispatch( + event.target, + 'debugger:edit-breakpoint'); + + } }, 'Condition: ', + breakpoint.condition) : + + null; + + const content = + _react.createElement('div', { className: 'inline-block' }, + _react.createElement('div', { + className: (0, (_classnames || _load_classnames()).default)({ + 'debugger-breakpoint-disabled': !enabled, + 'debugger-breakpoint-with-condition': Boolean( + breakpoint.condition) }), + + + key: i }, + _react.createElement((_Checkbox || _load_Checkbox()).Checkbox, { + checked: enabled, + onChange: this._handleBreakpointEnabledChange.bind( + this, + breakpoint), + + onClick: event => event.stopPropagation(), + title: title, + className: (0, (_classnames || _load_classnames()).default)( + verified ? '' : 'debugger-breakpoint-unresolved', + 'debugger-breakpoint-checkbox') }), + + + _react.createElement('span', { + title: title, + 'data-path': path, + 'data-bpid': bpId, + 'data-line': line }, + _react.createElement('div', { className: 'debugger-breakpoint-condition-controls' }, + _react.createElement((_Icon || _load_Icon()).Icon, { + icon: 'pencil', + className: 'debugger-breakpoint-condition-control', + 'data-path': path, + 'data-bpid': bpId, + 'data-line': line, + onClick: event => { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_EDIT_BREAKPOINT_FROM_ICON); + atom.commands.dispatch( + event.target, + 'debugger:edit-breakpoint'); + + } }), + + _react.createElement((_Icon || _load_Icon()).Icon, { + icon: 'x', + className: 'debugger-breakpoint-condition-control', + 'data-path': path, + 'data-bpid': bpId, + 'data-line': line, + onClick: event => { + (0, (_analytics || _load_analytics()).track)( + (_constants || _load_constants()).AnalyticsEvents.DEBUGGER_DELETE_BREAKPOINT_FROM_ICON); + + atom.commands.dispatch( event.target, - 'debugger:edit-breakpoint', - ); - }}> - Condition: {breakpoint.condition} -
- ) : null; - - const content = ( -
-
- ) => event.stopPropagation()} - title={title} - className={classnames( - verified ? '' : 'debugger-breakpoint-unresolved', - 'debugger-breakpoint-checkbox', - )} - /> - -
- { - track(AnalyticsEvents.DEBUGGER_EDIT_BREAKPOINT_FROM_ICON); - atom.commands.dispatch( - event.target, - 'debugger:edit-breakpoint', - ); - }} - /> - { - track( - AnalyticsEvents.DEBUGGER_DELETE_BREAKPOINT_FROM_ICON, - ); - atom.commands.dispatch( - event.target, - 'debugger:remove-breakpoint', - ); - event.stopPropagation(); - }} - /> -
- {label} -
- {conditionElement} -
-
- ); - return ( - - {content} - - ); - }); + 'debugger:remove-breakpoint'); + + event.stopPropagation(); + } })), + + + label), + + conditionElement)); + + + + return ( + _react.createElement((_ListView || _load_ListView()).ListViewItem, { + key: label, + index: i, + value: breakpoint, + 'data-path': path, + 'data-bpid': bpId, + 'data-line': line, + title: title, + className: 'debugger-breakpoint' }, + content)); + + + }); const separator = - breakpoints.length !== 0 ? ( -
- ) : null; + breakpoints.length !== 0 ? + _react.createElement('hr', { className: 'nuclide-ui-hr debugger-breakpoint-separator' }) : + null; return ( -
- {exceptionBreakpoints.map(exceptionBreakpoint => { + _react.createElement('div', null, + exceptionBreakpoints.map(exceptionBreakpoint => { return ( -
- - service.enableOrDisableBreakpoints( - enabled, - exceptionBreakpoint, - ) - } - checked={exceptionBreakpoint.enabled} - /> - {exceptionBreakpoint.label || - `${exceptionBreakpoint.filter} exceptions`} -
- ); - })} - {separator} - - {items} - -
- ); - } -} + _react.createElement('div', { + className: 'debugger-breakpoint', + key: exceptionBreakpoint.getId() }, + _react.createElement((_Checkbox || _load_Checkbox()).Checkbox, { + className: (0, (_classnames || _load_classnames()).default)( + 'debugger-breakpoint-checkbox', + 'debugger-exception-checkbox'), + + onChange: enabled => + service.enableOrDisableBreakpoints( + enabled, + exceptionBreakpoint), + + + checked: exceptionBreakpoint.enabled }), + + exceptionBreakpoint.label || + `${exceptionBreakpoint.filter} exceptions`)); + + + }), + separator, + _react.createElement((_ListView || _load_ListView()).ListView, { + alternateBackground: true, + onSelect: this._handleBreakpointClick, + selectable: true }, + items))); + + + + }}exports.default = BreakpointListComponent; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/BreakpointsView.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/BreakpointsView.js index 06dffe33..e90855ec 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/BreakpointsView.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/BreakpointsView.js @@ -1,39 +1,38 @@ -/** - * 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 - * @format - */ - -import type {IDebugService} from '../types'; - -import classnames from 'classnames'; -import * as React from 'react'; -import BreakpointListComponent from './BreakpointListComponent'; - -type Props = { - service: IDebugService, -}; - -export default class BreakpointsView extends React.PureComponent { - render(): React.Node { - const {service} = this.props; - - return ( -
-
- -
-
- ); - } -} + 'debugger-breakpoint-list') }, + + _react.createElement('div', { className: 'debugger-pane-content ' }, + _react.createElement((_BreakpointListComponent || _load_BreakpointListComponent()).default, { service: service })))); + + + + }}exports.default = BreakpointsView; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerCallstackComponent.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerCallstackComponent.js index b100e82b..4c0a9b22 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerCallstackComponent.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerCallstackComponent.js @@ -1,226 +1,236 @@ -/** - * 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 - * @format - */ - -import type {DebuggerModeType, IDebugService, IStackFrame} from '../types'; -import * as React from 'react'; - -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {UNKNOWN_SOURCE, DebuggerMode} from '../constants'; -import {Table} from 'nuclide-commons-ui/Table'; -import {Observable} from 'rxjs'; -import {fastDebounce} from 'nuclide-commons/observable'; -import nullthrows from 'nullthrows'; -// eslint-disable-next-line rulesdir/prefer-nuclide-uri -import * as path from 'path'; -import classnames from 'classnames'; -import idx from 'idx'; -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import {Button, ButtonSizes} from 'nuclide-commons-ui/Button'; -import { - LoadingSpinner, - LoadingSpinnerSizes, -} from 'nuclide-commons-ui/LoadingSpinner'; - -type Props = { - service: IDebugService, -}; - -type State = { - mode: DebuggerModeType, - callstack: Array, - selectedCallFrameId: number, - callStackLevels: number, - isFechingStackFrames: boolean, -}; - -export default class DebuggerCallstackComponent extends React.Component< - Props, - State, -> { - _disposables: UniversalDisposable; - - constructor(props: Props) { - super(props); - this._disposables = new UniversalDisposable(); +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); + + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react'));var _event; + +function _load_event() {return _event = require('nuclide-commons/event');}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _constants; +function _load_constants() {return _constants = require('../constants');}var _Table; +function _load_Table() {return _Table = require('nuclide-commons-ui/Table');} +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _observable; +function _load_observable() {return _observable = require('nuclide-commons/observable');}var _nullthrows; +function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));} + +var _path = _interopRequireWildcard(require('path'));var _classnames; +function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));}var _idx; +function _load_idx() {return _idx = _interopRequireDefault(require('idx'));}var _AtomInput; +function _load_AtomInput() {return _AtomInput = require('nuclide-commons-ui/AtomInput');}var _Button; +function _load_Button() {return _Button = require('nuclide-commons-ui/Button');}var _LoadingSpinner; +function _load_LoadingSpinner() {return _LoadingSpinner = require('nuclide-commons-ui/LoadingSpinner');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} // eslint-disable-next-line rulesdir/prefer-nuclide-uri + + + + + + + + + + + + + + + + +class DebuggerCallstackComponent extends _react.Component + + +{ + + + constructor(props) { + super(props);_initialiseProps.call(this); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this.state = this._getState(); } - _getState(): State { - const {service} = this.props; - const {focusedStackFrame, focusedThread} = service.viewModel; + _getState() { + const { service } = this.props; + const { focusedStackFrame, focusedThread } = service.viewModel; return { callStackLevels: this.state == null ? 20 : this.state.callStackLevels, mode: service.getDebuggerMode(), callstack: focusedThread == null ? [] : focusedThread.getCallStack(), selectedCallFrameId: - focusedStackFrame == null ? -1 : focusedStackFrame.frameId, - isFechingStackFrames: false, - }; + focusedStackFrame == null ? -1 : focusedStackFrame.frameId, + isFechingStackFrames: false }; + } - _locationComponent = (props: { - // eslint-disable-next-line react/no-unused-prop-types - data: IStackFrame, - }): React.Element => { - const {source, range} = props.data; - const name = - source.name != null - ? source.name - : path.basename(source.uri) || UNKNOWN_SOURCE; - - // Note: IStackFrame ranges are 0-based. - return ( -
- - {name}:{range.start.row + 1} - -
- ); - }; - - componentDidMount(): void { - const {service} = this.props; + + + + + + + + + + + + + + + + + + + + + componentDidMount() { + const { service } = this.props; const model = service.getModel(); - const {viewModel} = service; + const { viewModel } = service; this._disposables.add( - Observable.merge( - observableFromSubscribeFunction(model.onDidChangeCallStack.bind(model)), - observableFromSubscribeFunction( - viewModel.onDidFocusStackFrame.bind(viewModel), - ), - observableFromSubscribeFunction(service.onDidChangeMode.bind(service)), - ) - .let(fastDebounce(15)) - .subscribe(() => this.setState(this._getState())), - ); + _rxjsBundlesRxMinJs.Observable.merge( + (0, (_event || _load_event()).observableFromSubscribeFunction)(model.onDidChangeCallStack.bind(model)), + (0, (_event || _load_event()).observableFromSubscribeFunction)( + viewModel.onDidFocusStackFrame.bind(viewModel)), + + (0, (_event || _load_event()).observableFromSubscribeFunction)(service.onDidChangeMode.bind(service))). + + let((0, (_observable || _load_observable()).fastDebounce)(15)). + subscribe(() => this.setState(this._getState()))); + } - componentWillUnmount(): void { + componentWillUnmount() { this._disposables.dispose(); } - _handleStackFrameClick = ( - clickedRow: {frame: IStackFrame}, - callFrameIndex: number, - ): void => { - this.props.service.focusStackFrame(clickedRow.frame, null, null, true); - }; - render(): React.Node { - const {callstack, mode} = this.state; + + + + + + + render() { + const { callstack, mode } = this.state; const rows = - callstack == null - ? [] - : callstack.map((stackFrame, index) => { - const isSelected = - this.state.selectedCallFrameId === stackFrame.frameId; - const cellData = { - data: { - frameId: index + 1, - address: stackFrame.name, - frame: stackFrame, - isSelected, - }, - }; - - if (isSelected) { - // $FlowIssue className is an optional property of a table row - cellData.className = 'debugger-callstack-item-selected'; - } + callstack == null ? + [] : + callstack.map((stackFrame, index) => { + const isSelected = + this.state.selectedCallFrameId === stackFrame.frameId; + const cellData = { + data: { + frameId: index + 1, + address: stackFrame.name, + frame: stackFrame, + isSelected } }; - return cellData; - }); + + + if (isSelected) { + // $FlowIssue className is an optional property of a table row + cellData.className = 'debugger-callstack-item-selected'; + } + + return cellData; + }); const columns = [ - { - title: '', - key: 'frameId', - width: 0.05, - }, - { - title: 'Address', - key: 'address', - }, - { - component: this._locationComponent, - title: 'File Location', - key: 'frame', - }, - ]; - - const emptyComponent = () => ( -
callstack unavailable
- ); + { + title: '', + key: 'frameId', + width: 0.05 }, + + { + title: 'Address', + key: 'address' }, + + { + component: this._locationComponent, + title: 'File Location', + key: 'frame' }]; + + + + const emptyComponent = () => + _react.createElement('div', { className: 'debugger-callstack-list-empty' }, 'callstack unavailable'); + return ( -
-
- cellData.frame.source.available} - resizable={true} - onSelect={this._handleStackFrameClick} - sortable={false} - /> - {this._renderLoadMoreStackFrames()} - - - ); + _react.createElement('div', { + className: (0, (_classnames || _load_classnames()).default)('debugger-container-new', { + 'debugger-container-new-disabled': mode === (_constants || _load_constants()).DebuggerMode.RUNNING }) }, + + _react.createElement('div', { className: 'debugger-pane-content' }, + _react.createElement((_Table || _load_Table()).Table, { + className: 'debugger-callstack-table', + columns: columns, + emptyComponent: emptyComponent, + rows: rows, + selectable: cellData => cellData.frame.source.available, + resizable: true, + onSelect: this._handleStackFrameClick, + sortable: false }), + + this._renderLoadMoreStackFrames()))); + + + } - _renderLoadMoreStackFrames(): ?React.Element { - const {viewModel} = this.props.service; - const {callstack, isFechingStackFrames} = this.state; + _renderLoadMoreStackFrames() {var _ref, _ref2, _ref3; + const { viewModel } = this.props.service; + const { callstack, isFechingStackFrames } = this.state; const totalFrames = - idx(viewModel, _ => _.focusedThread.stoppedDetails.totalFrames) || 0; + ((_ref = viewModel) != null ? (_ref2 = _ref.focusedThread) != null ? (_ref3 = _ref2.stoppedDetails) != null ? _ref3.totalFrames : _ref3 : _ref2 : _ref) || 0; if (totalFrames <= callstack.length || callstack.length <= 1) { return null; } return ( -
- - { + _react.createElement('div', { style: { display: 'flex' } }, + _react.createElement((_Button || _load_Button()).Button, { + size: (_Button || _load_Button()).ButtonSizes.EXTRA_SMALL, + disabled: isFechingStackFrames, + onClick: () => { + this.setState({ isFechingStackFrames: true }); + (0, (_nullthrows || _load_nullthrows()).default)(viewModel.focusedThread). + fetchCallStack(this.state.callStackLevels). + then(() => this.setState(this._getState())); + } }, 'More Stack Frames'), + + + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + style: { 'flex-grow': '1' }, + placeholderText: 'Number of stack frames', + initialValue: String(this.state.callStackLevels), + size: 'xs', + onDidChange: value => { if (!isNaN(value)) { - this.setState({callStackLevels: parseInt(value, 10)}); + this.setState({ callStackLevels: parseInt(value, 10) }); } - }} - /> - - {isFechingStackFrames ? ( - - ) : null} -
- ); - } -} + } }), + + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, null), + isFechingStackFrames ? + _react.createElement((_LoadingSpinner || _load_LoadingSpinner()).LoadingSpinner, { size: (_LoadingSpinner || _load_LoadingSpinner()).LoadingSpinnerSizes.EXTRA_SMALL }) : + null)); + + + }}exports.default = DebuggerCallstackComponent; /** + * 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. + * + * + * @format + */var _initialiseProps = function () {this._locationComponent = props => {const { source, range } = props.data;const name = source.name != null ? source.name : _path.basename(source.uri) || (_constants || _load_constants()).UNKNOWN_SOURCE; // Note: IStackFrame ranges are 0-based. + return _react.createElement('div', { title: `${name}:${range.start.row + 1}` }, _react.createElement('span', null, name, ':', range.start.row + 1));};this._handleStackFrameClick = (clickedRow, callFrameIndex) => {this.props.service.focusStackFrame(clickedRow.frame, null, null, true);};}; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerControllerView.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerControllerView.js index c3381710..156b26df 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerControllerView.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerControllerView.js @@ -1,59 +1,58 @@ -/** - * 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 - * @format - */ - -import type {IDebugService} from '../types'; - -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import * as React from 'react'; -import {LoadingSpinner} from 'nuclide-commons-ui/LoadingSpinner'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {DebuggerMode} from '../constants'; - -type Props = { - service: IDebugService, -}; - -export default class DebuggerControllerView extends React.Component { - _disposables: UniversalDisposable; - - constructor(props: Props) { - super(props); - this._disposables = new UniversalDisposable(); +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _event; + + + + + + + + + + + + + +function _load_event() {return _event = require('nuclide-commons/event');} +var _react = _interopRequireWildcard(require('react'));var _LoadingSpinner; +function _load_LoadingSpinner() {return _LoadingSpinner = require('nuclide-commons-ui/LoadingSpinner');}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _constants; +function _load_constants() {return _constants = require('../constants');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} /** + * 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. + * + * + * @format + */class DebuggerControllerView extends _react.Component {constructor(props) {super(props); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); } componentDidMount() { - const {service} = this.props; + const { service } = this.props; this._disposables.add( - observableFromSubscribeFunction( - service.onDidChangeMode.bind(service), - ).subscribe(mode => this.forceUpdate()), - ); + (0, (_event || _load_event()).observableFromSubscribeFunction)( + service.onDidChangeMode.bind(service)). + subscribe(mode => this.forceUpdate())); + } - componentWillUnmount(): void { + componentWillUnmount() { this._disposables.dispose(); } - render(): React.Node { - if (this.props.service.getDebuggerMode() === DebuggerMode.STARTING) { + render() { + if (this.props.service.getDebuggerMode() === (_constants || _load_constants()).DebuggerMode.STARTING) { return ( -
-
- Starting Debugger... - -
-
- ); + _react.createElement('div', { className: 'debugger-starting-message' }, + _react.createElement('div', null, + _react.createElement('span', { className: 'inline-block' }, 'Starting Debugger...'), + _react.createElement((_LoadingSpinner || _load_LoadingSpinner()).LoadingSpinner, { className: 'inline-block', size: 'EXTRA_SMALL' })))); + + + } return null; - } -} + }}exports.default = DebuggerControllerView; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerControlsView.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerControlsView.js index acbf296b..82c2952a 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerControlsView.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerControlsView.js @@ -1,136 +1,135 @@ -/** - * 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 - * @format - */ - -import type {DebuggerModeType, IDebugService} from '../types'; - -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import * as React from 'react'; -import TruncatedButton from 'nuclide-commons-ui/TruncatedButton'; -import DebuggerSteppingComponent from './DebuggerSteppingComponent'; -import {DebuggerMode} from '../constants'; -import DebuggerControllerView from './DebuggerControllerView'; -import {goToLocation} from 'nuclide-commons-atom/go-to-location'; - -const DEVICE_PANEL_URL = 'atom://nuclide/devices'; - -type Props = { - service: IDebugService, -}; - -type State = { - mode: DebuggerModeType, - hasDevicePanelService: boolean, -}; - -export default class DebuggerControlsView extends React.PureComponent< - Props, - State, -> { - _disposables: UniversalDisposable; - - constructor(props: Props) { +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _event; + + + + + + + + + + + + + +function _load_event() {return _event = require('nuclide-commons/event');}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));} +var _react = _interopRequireWildcard(require('react'));var _TruncatedButton; +function _load_TruncatedButton() {return _TruncatedButton = _interopRequireDefault(require('nuclide-commons-ui/TruncatedButton'));}var _DebuggerSteppingComponent; +function _load_DebuggerSteppingComponent() {return _DebuggerSteppingComponent = _interopRequireDefault(require('./DebuggerSteppingComponent'));}var _constants; +function _load_constants() {return _constants = require('../constants');}var _DebuggerControllerView; +function _load_DebuggerControllerView() {return _DebuggerControllerView = _interopRequireDefault(require('./DebuggerControllerView'));}var _goToLocation; +function _load_goToLocation() {return _goToLocation = require('nuclide-commons-atom/go-to-location');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +const DEVICE_PANEL_URL = 'atom://nuclide/devices'; /** + * 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. + * + * + * @format + */ +class DebuggerControlsView extends _react.PureComponent + + +{ + + + constructor(props) { super(props); - this._disposables = new UniversalDisposable(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this.state = { mode: props.service.getDebuggerMode(), - hasDevicePanelService: false, - }; + hasDevicePanelService: false }; + } - componentDidMount(): void { - const {service} = this.props; + componentDidMount() { + const { service } = this.props; this._disposables.add( - observableFromSubscribeFunction( - service.onDidChangeMode.bind(service), - ).subscribe(mode => this.setState({mode})), - atom.packages.serviceHub.consume('nuclide.devices', '0.0.0', provider => - this.setState({ - hasDevicePanelService: true, - }), - ), - ); + (0, (_event || _load_event()).observableFromSubscribeFunction)( + service.onDidChangeMode.bind(service)). + subscribe(mode => this.setState({ mode })), + atom.packages.serviceHub.consume('nuclide.devices', '0.0.0', provider => + this.setState({ + hasDevicePanelService: true }))); + + + } - componentWillUnmount(): void { + componentWillUnmount() { this._dispose(); } - _dispose(): void { + _dispose() { this._disposables.dispose(); } - render(): React.Node { - const {service} = this.props; - const {mode} = this.state; + render() { + const { service } = this.props; + const { mode } = this.state; const debuggerStoppedNotice = - mode !== DebuggerMode.STOPPED ? null : ( -
-
- The debugger is not attached. -
- - atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'debugger:show-attach-dialog', - ) - } - icon="nuclicon-debugger" - label="Attach debugger..." - /> - - atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'debugger:show-launch-dialog', - ) - } - icon="nuclicon-debugger" - label="Launch debugger..." - /> - {this.state.hasDevicePanelService ? ( - goToLocation(DEVICE_PANEL_URL)} - icon="device-mobile" - label="Manage devices..." - /> - ) : null} -
-
-
- ); + mode !== (_constants || _load_constants()).DebuggerMode.STOPPED ? null : + _react.createElement('div', { className: 'debugger-pane-content' }, + _react.createElement('div', { className: 'debugger-state-notice' }, + _react.createElement('span', null, 'The debugger is not attached.'), + _react.createElement('div', { className: 'padded' }, + _react.createElement((_TruncatedButton || _load_TruncatedButton()).default, { + onClick: () => + atom.commands.dispatch( + atom.views.getView(atom.workspace), + 'debugger:show-attach-dialog'), + + + icon: 'nuclicon-debugger', + label: 'Attach debugger...' }), + + _react.createElement((_TruncatedButton || _load_TruncatedButton()).default, { + onClick: () => + atom.commands.dispatch( + atom.views.getView(atom.workspace), + 'debugger:show-launch-dialog'), + + + icon: 'nuclicon-debugger', + label: 'Launch debugger...' }), + + this.state.hasDevicePanelService ? + _react.createElement((_TruncatedButton || _load_TruncatedButton()).default, { + onClick: () => (0, (_goToLocation || _load_goToLocation()).goToLocation)(DEVICE_PANEL_URL), + icon: 'device-mobile', + label: 'Manage devices...' }) : + + null))); + + + + const debugeeRunningNotice = - mode !== DebuggerMode.RUNNING ? null : ( -
-
- The debug target is currently running. -
-
- ); + mode !== (_constants || _load_constants()).DebuggerMode.RUNNING ? null : + _react.createElement('div', { className: 'debugger-pane-content' }, + _react.createElement('div', { className: 'debugger-state-notice' }, 'The debug target is currently running.')); + + + + return ( -
-
- -
-
- -
- {debugeeRunningNotice} - {debuggerStoppedNotice} -
- ); - } -} + _react.createElement('div', { className: 'debugger-container-new' }, + _react.createElement('div', { className: 'debugger-section-header' }, + _react.createElement((_DebuggerControllerView || _load_DebuggerControllerView()).default, { service: service })), + + _react.createElement('div', { className: 'debugger-section-header debugger-controls-section' }, + _react.createElement((_DebuggerSteppingComponent || _load_DebuggerSteppingComponent()).default, { service: service })), + + debugeeRunningNotice, + debuggerStoppedNotice)); + + + }}exports.default = DebuggerControlsView; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerDatatipComponent.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerDatatipComponent.js index acc853ee..2734ca49 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerDatatipComponent.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerDatatipComponent.js @@ -1,47 +1,46 @@ -/** - * 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 - * @format - */ - -import type {EvaluationResult} from 'nuclide-commons-ui/TextRenderer'; - -import {LoadingSpinner} from 'nuclide-commons-ui/LoadingSpinner'; -import * as React from 'react'; -import {LazyNestedValueComponent} from 'nuclide-commons-ui/LazyNestedValueComponent'; -import SimpleValueComponent from 'nuclide-commons-ui/SimpleValueComponent'; -import {fetchChildrenForLazyComponent} from '../utils'; - -type Props = {| - +expression: string, - +evaluationResult: ?EvaluationResult, -|}; - -export default class DebuggerDatatipComponent extends React.Component { - render(): React.Node { - const {expression, evaluationResult} = this.props; - let datatipElement; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _LoadingSpinner; + + + + + + + + + + + + + +function _load_LoadingSpinner() {return _LoadingSpinner = require('nuclide-commons-ui/LoadingSpinner');} +var _react = _interopRequireWildcard(require('react'));var _LazyNestedValueComponent; +function _load_LazyNestedValueComponent() {return _LazyNestedValueComponent = require('nuclide-commons-ui/LazyNestedValueComponent');}var _SimpleValueComponent; +function _load_SimpleValueComponent() {return _SimpleValueComponent = _interopRequireDefault(require('nuclide-commons-ui/SimpleValueComponent'));}var _utils; +function _load_utils() {return _utils = require('../utils');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} /** + * 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. + * + * + * @format + */class DebuggerDatatipComponent extends _react.Component {render() {const { expression, evaluationResult } = this.props;let datatipElement; if (evaluationResult == null) { - datatipElement = ; + datatipElement = _react.createElement((_LoadingSpinner || _load_LoadingSpinner()).LoadingSpinner, { delay: 100, size: 'EXTRA_SMALL' }); } else { - datatipElement = ( - - - - ); + datatipElement = + _react.createElement('span', { className: 'debugger-datatip-value' }, + _react.createElement((_LazyNestedValueComponent || _load_LazyNestedValueComponent()).LazyNestedValueComponent, { + evaluationResult: evaluationResult, + expression: expression, + fetchChildren: (_utils || _load_utils()).fetchChildrenForLazyComponent, + simpleValueComponent: (_SimpleValueComponent || _load_SimpleValueComponent()).default, + expansionStateId: this })); + + + } - return
{datatipElement}
; - } -} + return _react.createElement('div', { className: 'debugger-datatip' }, datatipElement); + }}exports.default = DebuggerDatatipComponent; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerLaunchAttachUI.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerLaunchAttachUI.js index 34c842bf..34c4edf0 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerLaunchAttachUI.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerLaunchAttachUI.js @@ -1,232 +1,232 @@ -/** - * 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 - * @format - */ -/* global localStorage */ - -import type { - DebuggerConfigAction, - DebuggerLaunchAttachProvider, -} from 'nuclide-debugger-common'; -import type {Tab} from 'nuclide-commons-ui/Tabs'; - -import * as React from 'react'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {Button, ButtonTypes} from 'nuclide-commons-ui/Button'; -import {ButtonGroup} from 'nuclide-commons-ui/ButtonGroup'; -import {Dropdown} from 'nuclide-commons-ui/Dropdown'; -import Tabs from 'nuclide-commons-ui/Tabs'; -import {Observable} from 'rxjs'; -import invariant from 'assert'; -import {isNuclideEnvironment} from '../AtomServiceContainer'; - -type ConnectionOption = { - value: string, - label: string, -}; - -type EnabledProvider = {| - provider: DebuggerLaunchAttachProvider, - debuggerName: string, -|}; - -type Props = {| - +dialogMode: DebuggerConfigAction, - +connection: string, - +connectionChanged: (newValue: ?string) => void, - // $FlowFixMe - +connectionOptions: Array, - +providers: Map>, - +dialogCloser: () => void, -|}; - -type State = { - selectedProviderTab: ?string, - configIsValid: boolean, - enabledProviders: Array, -}; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + + + + + + + + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react'));var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _nuclideUri; +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));}var _Button; +function _load_Button() {return _Button = require('nuclide-commons-ui/Button');}var _ButtonGroup; +function _load_ButtonGroup() {return _ButtonGroup = require('nuclide-commons-ui/ButtonGroup');}var _Dropdown; +function _load_Dropdown() {return _Dropdown = require('nuclide-commons-ui/Dropdown');}var _Tabs; +function _load_Tabs() {return _Tabs = _interopRequireDefault(require('nuclide-commons-ui/Tabs'));} +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _AtomServiceContainer; + +function _load_AtomServiceContainer() {return _AtomServiceContainer = require('../AtomServiceContainer');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + + + + + + + + + + + + + + + + + + + + + + + + + + // TODO those should be managed by the debugger store state function setLastUsedDebugger( - host: string, - action: DebuggerConfigAction, - debuggerDisplayName: string, -): void { +host, +action, +debuggerDisplayName) +{ const key = 'DEBUGGER_LAST_USED_' + host + '_' + action; localStorage.setItem(key, debuggerDisplayName); -} +} /** + * 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. + * + * + * @format + */ /* global localStorage */function getLastUsedDebugger(host, action) {const key = 'DEBUGGER_LAST_USED_' + host + '_' + action;return localStorage.getItem(key);}class DebuggerLaunchAttachUI extends _react.Component + + +{ + + + + + constructor(props) { + super(props);this. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -function getLastUsedDebugger( - host: string, - action: DebuggerConfigAction, -): ?string { - const key = 'DEBUGGER_LAST_USED_' + host + '_' + action; - return localStorage.getItem(key); -} - -export default class DebuggerLaunchAttachUI extends React.Component< - Props, - State, -> { - props: Props; - state: State; - _disposables: UniversalDisposable; - - constructor(props: Props) { - super(props); - - this._disposables = new UniversalDisposable(); - this._disposables.add( - atom.commands.add('atom-workspace', { - 'core:confirm': () => { - if (this.state.configIsValid) { - this._rememberTab(); - - // Close the dialog, but do it on the next tick so that the child - // component gets to handle the event first (and start the debugger). - process.nextTick(this.props.dialogCloser); - } - }, - }), - atom.commands.add('atom-workspace', { - 'core:cancel': () => { - this._rememberTab(); - this.props.dialogCloser(); - }, - }), - ); - - this.state = { - selectedProviderTab: null, - configIsValid: false, - enabledProviders: [], - }; - } - _rememberTab(): void { - // Remember the last tab the user used for this connection when the "launch/attach" - // button is clicked. - const host = nuclideUri.isRemote(this.props.connection) - ? nuclideUri.getHostname(this.props.connection) - : 'local'; - if (this.state.selectedProviderTab != null) { - setLastUsedDebugger( - host, - this.props.dialogMode, - this.state.selectedProviderTab || '', - ); - } - } - componentWillMount() { - const host = nuclideUri.isRemote(this.props.connection) - ? nuclideUri.getHostname(this.props.connection) - : 'local'; - this._filterProviders(host); - this.setState({ - selectedProviderTab: getLastUsedDebugger(host, this.props.dialogMode), - }); - } - componentWillReceiveProps(nextProps: Props) { - const host = nuclideUri.isRemote(nextProps.connection) - ? nuclideUri.getHostname(nextProps.connection) - : 'local'; - this._filterProviders(host); - this.setState({ - selectedProviderTab: getLastUsedDebugger(host, nextProps.dialogMode), - }); - } - componentWillUnmount() { - this._disposables.dispose(); - } - async _getProviderIfEnabled( - provider: DebuggerLaunchAttachProvider, - ): Promise { - const enabled = await provider - .getCallbacksForAction(this.props.dialogMode) - .isEnabled(); - return enabled ? provider : null; - } - _filterProviders(key: string): void { - this.setState({ - enabledProviders: [], - }); - - Observable.merge( - ...(this.props.providers.get(key) || []).map(provider => - Observable.fromPromise(this._getProviderIfEnabled(provider)), - ), - ) - .filter(provider => provider != null) - .subscribe(provider => { - invariant(provider != null); - const enabledProviders = this.state.enabledProviders.concat( - ...provider - .getCallbacksForAction(this.props.dialogMode) - .getDebuggerTypeNames() - .map(debuggerName => { - return { - provider, - debuggerName, - }; - }), - ); - - this.setState({ - enabledProviders, - }); - }); - } - _setConfigValid = (valid: boolean): void => { - this.setState({ - configIsValid: valid, - }); - }; - - _getTabsFromEnabledProviders(enabledProviders: EnabledProvider[]): Tab[] { - const tabs = this.state.enabledProviders - .map(debuggerType => ({ - name: debuggerType.debuggerName, - tabContent: ( - - {debuggerType.debuggerName} - - ), - })) - .sort((a, b) => a.name.localeCompare(b.name)); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _setConfigValid = valid => { + this.setState({ + configIsValid: valid }); + + };this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default();this._disposables.add(atom.commands.add('atom-workspace', { 'core:confirm': () => {if (this.state.configIsValid) {this._rememberTab(); // Close the dialog, but do it on the next tick so that the child + // component gets to handle the event first (and start the debugger). + process.nextTick(this.props.dialogCloser);}} }), atom.commands.add('atom-workspace', { 'core:cancel': () => {this._rememberTab();this.props.dialogCloser();} }));this.state = { selectedProviderTab: null, configIsValid: false, enabledProviders: [] };}_rememberTab() {// Remember the last tab the user used for this connection when the "launch/attach" + // button is clicked. + const host = (_nuclideUri || _load_nuclideUri()).default.isRemote(this.props.connection) ? (_nuclideUri || _load_nuclideUri()).default.getHostname(this.props.connection) : 'local';if (this.state.selectedProviderTab != null) {setLastUsedDebugger(host, this.props.dialogMode, this.state.selectedProviderTab || '');}}componentWillMount() {const host = (_nuclideUri || _load_nuclideUri()).default.isRemote(this.props.connection) ? (_nuclideUri || _load_nuclideUri()).default.getHostname(this.props.connection) : 'local';this._filterProviders(host);this.setState({ selectedProviderTab: getLastUsedDebugger(host, this.props.dialogMode) });}componentWillReceiveProps(nextProps) {const host = (_nuclideUri || _load_nuclideUri()).default.isRemote(nextProps.connection) ? (_nuclideUri || _load_nuclideUri()).default.getHostname(nextProps.connection) : 'local';this._filterProviders(host);this.setState({ selectedProviderTab: getLastUsedDebugger(host, nextProps.dialogMode) });}componentWillUnmount() {this._disposables.dispose();}_getProviderIfEnabled(provider) {var _this = this;return (0, _asyncToGenerator.default)(function* () {const enabled = yield provider.getCallbacksForAction(_this.props.dialogMode).isEnabled();return enabled ? provider : null;})();}_filterProviders(key) {this.setState({ enabledProviders: [] });_rxjsBundlesRxMinJs.Observable.merge(...(this.props.providers.get(key) || []).map(provider => _rxjsBundlesRxMinJs.Observable.fromPromise(this._getProviderIfEnabled(provider)))).filter(provider => provider != null).subscribe(provider => {if (!(provider != null)) {throw new Error('Invariant violation: "provider != null"');}const enabledProviders = this.state.enabledProviders.concat(...provider.getCallbacksForAction(this.props.dialogMode).getDebuggerTypeNames().map(debuggerName => {return { provider, debuggerName };}));this.setState({ enabledProviders });});}_getTabsFromEnabledProviders(enabledProviders) {const tabs = this.state.enabledProviders.map(debuggerType => ({ + name: debuggerType.debuggerName, + tabContent: + _react.createElement('span', { title: debuggerType.debuggerName }, + debuggerType.debuggerName) })). + + + + sort((a, b) => a.name.localeCompare(b.name)); return tabs; } setState( - partialState: $Shape | ((State, Props) => $Shape | void), - callback?: () => mixed, - ): void { + partialState, + callback) + { if (typeof partialState === 'function') { super.setState(partialState, callback); } else { - const fullState = { - ...this.state, - ...partialState, - }; + const fullState = Object.assign({}, + this.state, + partialState); + if (fullState.selectedProviderTab == null) { const tabs = this._getTabsFromEnabledProviders( - fullState.enabledProviders, - ); + fullState.enabledProviders); + if (tabs.length > 0) { const firstTab = tabs[0]; fullState.selectedProviderTab = firstTab.name; @@ -236,99 +236,98 @@ export default class DebuggerLaunchAttachUI extends React.Component< } } - render(): React.Node { + render() { const tabs = this._getTabsFromEnabledProviders(this.state.enabledProviders); let providerContent = null; if (tabs.length > 0) { let selectedTab = - this.state.selectedProviderTab != null - ? this.state.selectedProviderTab - : this.state.enabledProviders[0].debuggerName; + this.state.selectedProviderTab != null ? + this.state.selectedProviderTab : + this.state.enabledProviders[0].debuggerName; let provider = this.state.enabledProviders.find( - p => p.debuggerName === selectedTab, - ); + p => p.debuggerName === selectedTab); + if (provider == null) { provider = this.state.enabledProviders[0]; selectedTab = provider.debuggerName; } - const debuggerConfigPage = provider.provider - .getCallbacksForAction(this.props.dialogMode) - .getComponent(selectedTab, valid => this._setConfigValid(valid)); - - providerContent = ( -
- { - this._setConfigValid(false); - this.setState({selectedProviderTab: newTab.name}); - }} - /> -
- {debuggerConfigPage} -
-
- ); + const debuggerConfigPage = provider.provider. + getCallbacksForAction(this.props.dialogMode). + getComponent(selectedTab, valid => this._setConfigValid(valid)); + + providerContent = + _react.createElement('div', null, + _react.createElement((_Tabs || _load_Tabs()).default, { + className: 'debugger-launch-attach-tabs', + tabs: tabs, + activeTabName: this.state.selectedProviderTab, + triggeringEvent: 'onClick', + onActiveTabChange: newTab => { + this._setConfigValid(false); + this.setState({ selectedProviderTab: newTab.name }); + } }), + + _react.createElement('div', { className: 'debugger-launch-attach-tabcontent' }, + debuggerConfigPage)); + + + } else { // No debugging providers available. - providerContent = ( -
- No debuggers installed, look for available debuggers on{' '} - - atom.io/packages - -
- ); + providerContent = + _react.createElement('div', { className: 'debugger-launch-attach-tabcontent' }, 'No debuggers installed, look for available debuggers on', + ' ', + _react.createElement('a', { href: 'https://atom.io/packages/search?q=atom-ide-debugger-' }, 'atom.io/packages')); + + + + } return ( -
- {isNuclideEnvironment() ? ( -

- - {this.props.dialogMode === 'attach' - ? 'Attach debugger to ' - : 'Launch debugger on '} - - this.props.connectionChanged(value)} - size="xs" - value={this.props.connection} - /> -

- ) : null} - {providerContent} -
- - - - -
-
- ); - } -} + atom.views.getView(atom.workspace), + 'core:confirm') }, + + + this.props.dialogMode === 'attach' ? 'Attach' : 'Launch'))))); + + + + + + }}exports.default = DebuggerLaunchAttachUI; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerLayoutManager.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerLayoutManager.js index c0d28a9d..3f9aabe2 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerLayoutManager.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerLayoutManager.js @@ -1,92 +1,92 @@ -/** - * 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 - * @format - */ -/* global localStorage */ - -import type {DebuggerModeType, IDebugService, SerializedState} from '../types'; - -import * as React from 'react'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import DebuggerPaneViewModel from './DebuggerPaneViewModel'; -import DebuggerPaneContainerViewModel from './DebuggerPaneContainerViewModel'; -import {DebuggerMode, DEBUGGER_PANELS_DEFAULT_LOCATION} from '../constants'; -import invariant from 'assert'; -import createPaneContainer from 'nuclide-commons-atom/create-pane-container'; -import {destroyItemWhere} from 'nuclide-commons-atom/destroyItemWhere'; -import nullthrows from 'nullthrows'; +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); + + + + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react'));var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _DebuggerPaneViewModel; +function _load_DebuggerPaneViewModel() {return _DebuggerPaneViewModel = _interopRequireDefault(require('./DebuggerPaneViewModel'));}var _DebuggerPaneContainerViewModel; +function _load_DebuggerPaneContainerViewModel() {return _DebuggerPaneContainerViewModel = _interopRequireDefault(require('./DebuggerPaneContainerViewModel'));}var _constants; +function _load_constants() {return _constants = require('../constants');}var _createPaneContainer; + +function _load_createPaneContainer() {return _createPaneContainer = _interopRequireDefault(require('nuclide-commons-atom/create-pane-container'));}var _destroyItemWhere; +function _load_destroyItemWhere() {return _destroyItemWhere = require('nuclide-commons-atom/destroyItemWhere');}var _nullthrows; +function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));}var _DebuggerControlsView; + + +function _load_DebuggerControlsView() {return _DebuggerControlsView = _interopRequireDefault(require('./DebuggerControlsView'));}var _ThreadsView; +function _load_ThreadsView() {return _ThreadsView = _interopRequireDefault(require('./ThreadsView'));}var _DebuggerCallstackComponent; +function _load_DebuggerCallstackComponent() {return _DebuggerCallstackComponent = _interopRequireDefault(require('./DebuggerCallstackComponent'));}var _BreakpointsView; +function _load_BreakpointsView() {return _BreakpointsView = _interopRequireDefault(require('./BreakpointsView'));}var _ScopesView; +function _load_ScopesView() {return _ScopesView = _interopRequireDefault(require('./ScopesView'));}var _WatchView; +function _load_WatchView() {return _WatchView = _interopRequireDefault(require('./WatchView'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} + + + + + -// Debugger views -import DebuggerControlsView from './DebuggerControlsView'; -import ThreadsView from './ThreadsView'; -import DebuggerCallstackComponent from './DebuggerCallstackComponent'; -import BreakpointsView from './BreakpointsView'; -import ScopesView from './ScopesView'; -import WatchView from './WatchView'; - -export type DebuggerPaneLocation = { - dock: string, - layoutIndex: number, - userHidden: boolean, -}; // Configuration that defines a debugger pane. This controls what gets added // to the workspace when starting debugging. -export type DebuggerPaneConfig = { - // Each pane must provide a unique URI. - uri: string, - - // Function that returns the title for the pane. Some panes (like Threads) need - // to change their title depending on the debug target (ex "Threads" for C++ but - // "Requests" for PHP). - title: () => string, - - // Optional function that indicates if the pane is enabled for the current debug - // session. If not enabled, the pane won't be added to the workspace. - isEnabled?: () => boolean, - - // Boolean indicating if the debug session lifetime should be tied to this view. - // If true, the debug session will be terminated if this view is destroyed. - isLifetimeView: boolean, - - // Function that returns a view for Atom to use for the workspace pane. - createView: () => React.Element, - - // Optional filter function that lets panes specify that they should be shown - // or hidden depending on the debugger mode (ex don't show threads when stopped). - debuggerModeFilter?: (mode: DebuggerModeType) => boolean, - - // Structure to remember the pane's previous location if the user moved it around. - previousLocation?: ?DebuggerPaneLocation, - - // Location to use for layout if no user previous location is set. - defaultLocation: string, - - // Optional callback to be invoked when the pane is being resized (flex scale changed). - onPaneResize?: (pane: atom$Pane, newFlexScale: number) => boolean, -}; - -export default class DebuggerLayoutManager { - _disposables: UniversalDisposable; - _service: IDebugService; - _debuggerPanes: Array; - _previousDebuggerMode: DebuggerModeType; - _paneHiddenWarningShown: boolean; - _leftPaneContainerModel: ?DebuggerPaneContainerViewModel; - _rightPaneContainerModel: ?DebuggerPaneContainerViewModel; - _debuggerVisible: boolean; - - constructor(service: IDebugService, state: ?SerializedState) { - this._disposables = new UniversalDisposable(); +// Debugger views + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +class DebuggerLayoutManager { + + + + + + + + + + constructor(service, state) { + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._service = service; - this._previousDebuggerMode = DebuggerMode.STOPPED; + this._previousDebuggerMode = (_constants || _load_constants()).DebuggerMode.STOPPED; this._paneHiddenWarningShown = false; this._leftPaneContainerModel = null; this._rightPaneContainerModel = null; @@ -104,60 +104,60 @@ export default class DebuggerLayoutManager { }); } - dispose(): void { + dispose() { this._disposables.dispose(); } - registerContextMenus(): void { + registerContextMenus() { // Add context menus to let the user restore hidden panes. this._debuggerPanes.forEach(pane => { const command = `debugger:show-window-${pane.title().replace(/ /g, '-')}`; this._disposables.add( - atom.commands.add('atom-workspace', { - [String(command)]: () => this.showHiddenDebuggerPane(pane.uri), - }), - ); + atom.commands.add('atom-workspace', { + [String(command)]: () => this.showHiddenDebuggerPane(pane.uri) })); + + this._disposables.add( - atom.contextMenu.add({ - '.debugger-container': [ - { - label: 'Debugger Views', - submenu: [ - { - label: `Show ${pane.title()} window`, - command, - shouldDisplay: event => { - const debuggerPane = this._debuggerPanes.find( - p => p.uri === pane.uri, - ); - if ( - debuggerPane != null && - (debuggerPane.isEnabled == null || - debuggerPane.isEnabled()) - ) { - return ( - debuggerPane.previousLocation != null && - debuggerPane.previousLocation.userHidden - ); - } - return false; - }, - }, - ], - }, - ], - }), - ); + atom.contextMenu.add({ + '.debugger-container': [ + { + label: 'Debugger Views', + submenu: [ + { + label: `Show ${pane.title()} window`, + command, + shouldDisplay: event => { + const debuggerPane = this._debuggerPanes.find( + p => p.uri === pane.uri); + + if ( + debuggerPane != null && ( + debuggerPane.isEnabled == null || + debuggerPane.isEnabled())) + { + return ( + debuggerPane.previousLocation != null && + debuggerPane.previousLocation.userHidden); + + } + return false; + } }] }] })); + + + + + + }); } _overridePaneInitialHeight( - dockPane: atom$Pane, - newFlexScale: number, - desiredHeight: number, - ): void { - invariant(dockPane.element != null); + dockPane, + newFlexScale, + desiredHeight) + {if (!( + dockPane.element != null)) {throw new Error('Invariant violation: "dockPane.element != null"');} if (newFlexScale === 1) { // newFlexScale === 1 when the pane is added the first time. @@ -179,7 +179,7 @@ export default class DebuggerLayoutManager { } } - _initializeDebuggerPanes(): void { + _initializeDebuggerPanes() { const debuggerUriBase = 'atom://nuclide/debugger-'; const getFocusedProcess = () => this._service.viewModel.focusedProcess; @@ -187,92 +187,92 @@ export default class DebuggerLayoutManager { // controls from top to bottom in the order they're defined here. After that, the // user is free to move them around. this._debuggerPanes = [ - { - uri: debuggerUriBase + 'controls', - isLifetimeView: true, - title: () => 'Debugger', - defaultLocation: DEBUGGER_PANELS_DEFAULT_LOCATION, - isEnabled: () => true, - createView: () => , - onPaneResize: (dockPane, newFlexScale) => { - // If newFlexScale !== 1, that means the user must have resized this pane. - // Return true to unhook this callback and let the pane resize per Atom's - // default behavior. The user is now responsible for the pane's height. - return newFlexScale !== 1; - }, - }, - { - uri: debuggerUriBase + 'callstack', - isLifetimeView: false, - defaultLocation: DEBUGGER_PANELS_DEFAULT_LOCATION, - title: () => 'Call Stack', - isEnabled: () => true, - createView: () => ( - - ), - debuggerModeFilter: (mode: DebuggerModeType) => - mode !== DebuggerMode.STOPPED, - }, - { - uri: debuggerUriBase + 'breakpoints', - isLifetimeView: false, - defaultLocation: DEBUGGER_PANELS_DEFAULT_LOCATION, - title: () => 'Breakpoints', - isEnabled: () => true, - createView: () => , - }, - { - uri: debuggerUriBase + 'scopes', - isLifetimeView: false, - defaultLocation: DEBUGGER_PANELS_DEFAULT_LOCATION, - title: () => 'Scopes', - isEnabled: () => true, - createView: () => , - debuggerModeFilter: (mode: DebuggerModeType) => - mode !== DebuggerMode.STOPPED, - }, - { - uri: debuggerUriBase + 'watch-expressions', - isLifetimeView: false, - defaultLocation: DEBUGGER_PANELS_DEFAULT_LOCATION, - title: () => 'Watch Expressions', - isEnabled: () => true, - createView: () => , - }, - { - uri: debuggerUriBase + 'threads', - isLifetimeView: false, - defaultLocation: DEBUGGER_PANELS_DEFAULT_LOCATION, - title: () => - getFocusedProcess() == null - ? 'Threads' - : nullthrows(getFocusedProcess()).configuration.properties - .threadsComponentTitle, - isEnabled: () => - getFocusedProcess() == null - ? false - : nullthrows(getFocusedProcess()).configuration.capabilities - .threads, - createView: () => , - debuggerModeFilter: (mode: DebuggerModeType) => - mode !== DebuggerMode.STOPPED, - }, - ]; + { + uri: debuggerUriBase + 'controls', + isLifetimeView: true, + title: () => 'Debugger', + defaultLocation: (_constants || _load_constants()).DEBUGGER_PANELS_DEFAULT_LOCATION, + isEnabled: () => true, + createView: () => _react.createElement((_DebuggerControlsView || _load_DebuggerControlsView()).default, { service: this._service }), + onPaneResize: (dockPane, newFlexScale) => { + // If newFlexScale !== 1, that means the user must have resized this pane. + // Return true to unhook this callback and let the pane resize per Atom's + // default behavior. The user is now responsible for the pane's height. + return newFlexScale !== 1; + } }, + + { + uri: debuggerUriBase + 'callstack', + isLifetimeView: false, + defaultLocation: (_constants || _load_constants()).DEBUGGER_PANELS_DEFAULT_LOCATION, + title: () => 'Call Stack', + isEnabled: () => true, + createView: () => + _react.createElement((_DebuggerCallstackComponent || _load_DebuggerCallstackComponent()).default, { service: this._service }), + + debuggerModeFilter: mode => + mode !== (_constants || _load_constants()).DebuggerMode.STOPPED }, + + { + uri: debuggerUriBase + 'breakpoints', + isLifetimeView: false, + defaultLocation: (_constants || _load_constants()).DEBUGGER_PANELS_DEFAULT_LOCATION, + title: () => 'Breakpoints', + isEnabled: () => true, + createView: () => _react.createElement((_BreakpointsView || _load_BreakpointsView()).default, { service: this._service }) }, + + { + uri: debuggerUriBase + 'scopes', + isLifetimeView: false, + defaultLocation: (_constants || _load_constants()).DEBUGGER_PANELS_DEFAULT_LOCATION, + title: () => 'Scopes', + isEnabled: () => true, + createView: () => _react.createElement((_ScopesView || _load_ScopesView()).default, { service: this._service }), + debuggerModeFilter: mode => + mode !== (_constants || _load_constants()).DebuggerMode.STOPPED }, + + { + uri: debuggerUriBase + 'watch-expressions', + isLifetimeView: false, + defaultLocation: (_constants || _load_constants()).DEBUGGER_PANELS_DEFAULT_LOCATION, + title: () => 'Watch Expressions', + isEnabled: () => true, + createView: () => _react.createElement((_WatchView || _load_WatchView()).default, { service: this._service }) }, + + { + uri: debuggerUriBase + 'threads', + isLifetimeView: false, + defaultLocation: (_constants || _load_constants()).DEBUGGER_PANELS_DEFAULT_LOCATION, + title: () => + getFocusedProcess() == null ? + 'Threads' : + (0, (_nullthrows || _load_nullthrows()).default)(getFocusedProcess()).configuration.properties. + threadsComponentTitle, + isEnabled: () => + getFocusedProcess() == null ? + false : + (0, (_nullthrows || _load_nullthrows()).default)(getFocusedProcess()).configuration.capabilities. + threads, + createView: () => _react.createElement((_ThreadsView || _load_ThreadsView()).default, { service: this._service }), + debuggerModeFilter: mode => + mode !== (_constants || _load_constants()).DebuggerMode.STOPPED }]; + + this._restoreDebuggerPaneLocations(); } - _reshowDebuggerPanes(state: ?SerializedState): void { + _reshowDebuggerPanes(state) { if (state && state.showDebugger) { this.showDebuggerViews(); this._getWorkspaceDocks().forEach((dock, index) => { if ( - dock.dock.isVisible != null && - state.workspaceDocksVisibility != null && - !state.workspaceDocksVisibility[index] && - dock.dock.isVisible() && - dock.dock.hide != null - ) { + dock.dock.isVisible != null && + state.workspaceDocksVisibility != null && + !state.workspaceDocksVisibility[index] && + dock.dock.isVisible() && + dock.dock.hide != null) + { dock.dock.hide(); } }); @@ -283,7 +283,7 @@ export default class DebuggerLayoutManager { } } - _updateDebuggerVisibility(): void { + _updateDebuggerVisibility() { this._debuggerVisible = false; // See if any visible docks contain a pane that contains a debugger pane. @@ -291,14 +291,14 @@ export default class DebuggerLayoutManager { if (dock.dock.isVisible != null && dock.dock.isVisible()) { dock.dock.getPanes().forEach(pane => { if ( - pane - .getItems() - .find( - item => - item instanceof DebuggerPaneViewModel || - item instanceof DebuggerPaneContainerViewModel, - ) != null - ) { + pane. + getItems(). + find( + item => + item instanceof (_DebuggerPaneViewModel || _load_DebuggerPaneViewModel()).default || + item instanceof (_DebuggerPaneContainerViewModel || _load_DebuggerPaneContainerViewModel()).default) != + null) + { this._debuggerVisible = true; } }); @@ -306,7 +306,7 @@ export default class DebuggerLayoutManager { }); } - showHiddenDebuggerPane(uri: string): void { + showHiddenDebuggerPane(uri) { const pane = this._debuggerPanes.find(p => p.uri === uri); if (pane != null && pane.previousLocation != null) { pane.previousLocation.userHidden = false; @@ -315,56 +315,56 @@ export default class DebuggerLayoutManager { this.showDebuggerViews(); } - getModelForDebuggerUri(uri: string): any { + getModelForDebuggerUri(uri) { const config = this._debuggerPanes.find(pane => pane.uri === uri); if (config != null) { - return new DebuggerPaneViewModel(config, config.isLifetimeView, pane => - this._paneDestroyed(pane), - ); + return new (_DebuggerPaneViewModel || _load_DebuggerPaneViewModel()).default(config, config.isLifetimeView, pane => + this._paneDestroyed(pane)); + } return null; } - _getWorkspaceDocks(): Array<{ - name: string, - dock: atom$AbstractPaneContainer, - orientation: string, - }> { - const docks = new Array(4); + _getWorkspaceDocks() - invariant(atom.workspace.getLeftDock != null); + + + { + const docks = new Array(4);if (!( + + atom.workspace.getLeftDock != null)) {throw new Error('Invariant violation: "atom.workspace.getLeftDock != null"');} docks[0] = { name: 'left', dock: atom.workspace.getLeftDock(), - orientation: 'vertical', - }; + orientation: 'vertical' };if (!( - invariant(atom.workspace.getBottomDock != null); + + atom.workspace.getBottomDock != null)) {throw new Error('Invariant violation: "atom.workspace.getBottomDock != null"');} docks[1] = { name: 'bottom', dock: atom.workspace.getBottomDock(), - orientation: 'horizontal', - }; + orientation: 'horizontal' };if (!( + - invariant(atom.workspace.getCenter != null); + atom.workspace.getCenter != null)) {throw new Error('Invariant violation: "atom.workspace.getCenter != null"');} docks[2] = { name: 'center', dock: atom.workspace.getCenter(), - orientation: 'horizontal', - }; + orientation: 'horizontal' };if (!( - invariant(atom.workspace.getRightDock != null); + + atom.workspace.getRightDock != null)) {throw new Error('Invariant violation: "atom.workspace.getRightDock != null"');} docks[3] = { name: 'right', dock: atom.workspace.getRightDock(), - orientation: 'vertical', - }; + orientation: 'vertical' }; + return docks; } - _isDockEmpty(dock: atom$AbstractPaneContainer): boolean { + _isDockEmpty(dock) { const panes = dock.getPanes(); // A dock is empty for our purposes if it has nothing visible in it. If a dock @@ -372,18 +372,18 @@ export default class DebuggerLayoutManager { // in it, so check for no panes, or a single pane with no items. return ( panes.length === 0 || - (panes.length === 1 && panes[0].getItems().length === 0) - ); + panes.length === 1 && panes[0].getItems().length === 0); + } _appendItemToDock( - paneConfig: ?DebuggerPaneConfig, - dock: atom$AbstractPaneContainer, - item: Object, - debuggerItemsPerDock: Map, - ): void { - const panes = dock.getPanes(); - invariant(panes.length >= 1); + paneConfig, + dock, + item, + debuggerItemsPerDock) + { + const panes = dock.getPanes();if (!( + panes.length >= 1)) {throw new Error('Invariant violation: "panes.length >= 1"');} const dockPane = panes[panes.length - 1]; if (this._isDockEmpty(dock)) { @@ -393,7 +393,7 @@ export default class DebuggerLayoutManager { if (dockConfig == null) { // This item is being added to a nested PaneContainer rather than // directly to a dock. This is only done for vertical layouts. - dockConfig = {orientation: 'vertical'}; + dockConfig = { orientation: 'vertical' }; } if (dockConfig.orientation === 'horizontal') { @@ -416,8 +416,8 @@ export default class DebuggerLayoutManager { dockPane.activateItem(item); } else { dockPane.splitDown({ - items: [item], - }); + items: [item] }); + } } } @@ -439,21 +439,21 @@ export default class DebuggerLayoutManager { // If the debugger pane config has a custom layout callback, hook it up now. if (paneConfig != null && paneConfig.onPaneResize != null) { - const disposables = new UniversalDisposable(); + const disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); disposables.add(dockPane.onWillDestroy(() => disposables.dispose())); disposables.add( - dockPane.onDidChangeFlexScale(newFlexScale => { - invariant(paneConfig.onPaneResize != null); - if (paneConfig.onPaneResize(dockPane, newFlexScale)) { - // The callback has requested to be unregistered. - disposables.dispose(); - } - }), - ); + dockPane.onDidChangeFlexScale(newFlexScale => {if (!( + paneConfig.onPaneResize != null)) {throw new Error('Invariant violation: "paneConfig.onPaneResize != null"');} + if (paneConfig.onPaneResize(dockPane, newFlexScale)) { + // The callback has requested to be unregistered. + disposables.dispose(); + } + })); + } } - resetLayout(): void { + resetLayout() { // Remove all debugger panes from the UI. this.hideDebuggerViews(false); @@ -466,7 +466,7 @@ export default class DebuggerLayoutManager { // Forget all previous dock sizes; for (const dockInfo of this._getWorkspaceDocks()) { - const {name} = dockInfo; + const { name } = dockInfo; const key = this._getPaneStorageKey('dock-size' + name); localStorage.removeItem(key); } @@ -478,19 +478,19 @@ export default class DebuggerLayoutManager { this.showDebuggerViews(); } - _getPaneStorageKey(uri: string): string { + _getPaneStorageKey(uri) { return 'debugger-pane-location-' + uri; } - _deserializeSavedLocation(savedItem: string): ?DebuggerPaneLocation { + _deserializeSavedLocation(savedItem) { try { const obj = JSON.parse(savedItem); if ( - obj != null && - obj.dock != null && - obj.layoutIndex != null && - obj.userHidden != null - ) { + obj != null && + obj.dock != null && + obj.layoutIndex != null && + obj.userHidden != null) + { return obj; } } catch (e) {} @@ -498,42 +498,42 @@ export default class DebuggerLayoutManager { return null; } - _restoreDebuggerPaneLocations(): void { + _restoreDebuggerPaneLocations() { // See if there are saved previous locations for the debugger panes. for (const debuggerPane of this._debuggerPanes) { const savedItem = localStorage.getItem( - this._getPaneStorageKey(debuggerPane.uri), - ); + this._getPaneStorageKey(debuggerPane.uri)); + if (savedItem != null) { debuggerPane.previousLocation = this._deserializeSavedLocation( - savedItem, - ); + savedItem); + } } } - _saveDebuggerPaneLocations(): void { + _saveDebuggerPaneLocations() { for (const dockInfo of this._getWorkspaceDocks()) { - const {name, dock} = dockInfo; + const { name, dock } = dockInfo; const panes = dock.getPanes(); let layoutIndex = 0; let dockContainsDebuggerItem = false; for (const pane of panes) { for (const item of pane.getItems()) { const paneItems = []; - if (item instanceof DebuggerPaneContainerViewModel) { + if (item instanceof (_DebuggerPaneContainerViewModel || _load_DebuggerPaneContainerViewModel()).default) { paneItems.push(...item.getAllItems()); } else { paneItems.push(item); } for (const itemToSave of paneItems) { - if (itemToSave instanceof DebuggerPaneViewModel) { + if (itemToSave instanceof (_DebuggerPaneViewModel || _load_DebuggerPaneViewModel()).default) { const location = { dock: name, layoutIndex, - userHidden: false, - }; + userHidden: false }; + dockContainsDebuggerItem = true; itemToSave.getConfig().previousLocation = location; @@ -561,13 +561,13 @@ export default class DebuggerLayoutManager { } } - _shouldDestroyPaneItem(mode: DebuggerModeType, item: atom$PaneItem): boolean { - if (item instanceof DebuggerPaneViewModel) { + _shouldDestroyPaneItem(mode, item) { + if (item instanceof (_DebuggerPaneViewModel || _load_DebuggerPaneViewModel()).default) { const config = item.getConfig(); if ( - config.debuggerModeFilter != null && - !config.debuggerModeFilter(mode) - ) { + config.debuggerModeFilter != null && + !config.debuggerModeFilter(mode)) + { item.setRemovedFromLayout(true); return true; } @@ -575,23 +575,23 @@ export default class DebuggerLayoutManager { return false; } - debuggerModeChanged(): void { + debuggerModeChanged() { const mode = this._service.getDebuggerMode(); // Most panes disappear when the debugger is stopped, only keep // the ones that should still be shown. if ( - mode === DebuggerMode.STOPPING && - this._previousDebuggerMode !== DebuggerMode.STOPPED - ) { + mode === (_constants || _load_constants()).DebuggerMode.STOPPING && + this._previousDebuggerMode !== (_constants || _load_constants()).DebuggerMode.STOPPED) + { this._saveDebuggerPaneLocations(); - } else if (mode === DebuggerMode.STOPPED) { - destroyItemWhere(item => { - if (item instanceof DebuggerPaneContainerViewModel) { + } else if (mode === (_constants || _load_constants()).DebuggerMode.STOPPED) { + (0, (_destroyItemWhere || _load_destroyItemWhere()).destroyItemWhere)(item => { + if (item instanceof (_DebuggerPaneContainerViewModel || _load_DebuggerPaneContainerViewModel()).default) { // Forward the destruction logic to the contianer. item.destroyWhere(innerItem => - this._shouldDestroyPaneItem(mode, innerItem), - ); + this._shouldDestroyPaneItem(mode, innerItem)); + this._destroyContainerIfEmpty(item); return false; @@ -604,40 +604,40 @@ export default class DebuggerLayoutManager { this._previousDebuggerMode = mode; } - _countPanesForTargetDock(dockName: string, defaultDockName: string): number { + _countPanesForTargetDock(dockName, defaultDockName) { const mode = this._service.getDebuggerMode(); - return this._debuggerPanes - .filter( - // Filter out any panes that the user has hidden or that aren't visible - // in the current debug mode. - debuggerPane => - (debuggerPane.previousLocation == null || - !debuggerPane.previousLocation.userHidden) && - (debuggerPane.debuggerModeFilter == null || - debuggerPane.debuggerModeFilter(mode)), - ) - .map(debuggerPane => { - // Map each debugger pane to the name of the dock it will belong to. - if (debuggerPane.previousLocation != null) { - const previousDock = this._getWorkspaceDocks().find( - d => - debuggerPane.previousLocation != null && - d.name === debuggerPane.previousLocation.dock, - ); - if (previousDock != null) { - return previousDock.name; - } + return this._debuggerPanes. + filter( + // Filter out any panes that the user has hidden or that aren't visible + // in the current debug mode. + debuggerPane => + (debuggerPane.previousLocation == null || + !debuggerPane.previousLocation.userHidden) && ( + debuggerPane.debuggerModeFilter == null || + debuggerPane.debuggerModeFilter(mode))). + + map(debuggerPane => { + // Map each debugger pane to the name of the dock it will belong to. + if (debuggerPane.previousLocation != null) { + const previousDock = this._getWorkspaceDocks().find( + d => + debuggerPane.previousLocation != null && + d.name === debuggerPane.previousLocation.dock); + + if (previousDock != null) { + return previousDock.name; } - return defaultDockName; - }) - .filter(targetDockName => targetDockName === dockName).length; + } + return defaultDockName; + }). + filter(targetDockName => targetDockName === dockName).length; } - _getSavedDebuggerPaneSize(dock: { - name: string, - dock: atom$AbstractPaneContainer, - orientation: string, - }): ?number { + _getSavedDebuggerPaneSize(dock) + + + + { const key = this._getPaneStorageKey('dock-size' + dock.name); const savedItem = localStorage.getItem(key); if (savedItem != null) { @@ -650,45 +650,45 @@ export default class DebuggerLayoutManager { return null; } - showDebuggerViews(): void { + showDebuggerViews() { // Hide any debugger panes other than the controls so we have a known // starting point for preparing the layout. this.hideDebuggerViews(true); const addedItemsByDock = new Map(); const defaultDock = this._getWorkspaceDocks().find( - d => d.name === DEBUGGER_PANELS_DEFAULT_LOCATION, - ); - invariant(defaultDock != null); + d => d.name === (_constants || _load_constants()).DEBUGGER_PANELS_DEFAULT_LOCATION);if (!( + + defaultDock != null)) {throw new Error('Invariant violation: "defaultDock != null"');} - const leftDock = this._getWorkspaceDocks().find(d => d.name === 'left'); - invariant(leftDock != null); + const leftDock = this._getWorkspaceDocks().find(d => d.name === 'left');if (!( + leftDock != null)) {throw new Error('Invariant violation: "leftDock != null"');} let leftPaneContainer = null; if (this._countPanesForTargetDock(leftDock.name, defaultDock.name) > 0) { - leftPaneContainer = createPaneContainer(); + leftPaneContainer = (0, (_createPaneContainer || _load_createPaneContainer()).default)(); const size = this._getSavedDebuggerPaneSize(leftDock); this._leftPaneContainerModel = this._addPaneContainerToWorkspace( - leftPaneContainer, - leftDock.dock, - addedItemsByDock, - size, - ); + leftPaneContainer, + leftDock.dock, + addedItemsByDock, + size); + } - const rightDock = this._getWorkspaceDocks().find(d => d.name === 'right'); - invariant(rightDock != null); + const rightDock = this._getWorkspaceDocks().find(d => d.name === 'right');if (!( + rightDock != null)) {throw new Error('Invariant violation: "rightDock != null"');} let rightPaneContainer = null; if (this._countPanesForTargetDock(rightDock.name, defaultDock.name) > 0) { - rightPaneContainer = createPaneContainer(); + rightPaneContainer = (0, (_createPaneContainer || _load_createPaneContainer()).default)(); const size = this._getSavedDebuggerPaneSize(rightDock); this._rightPaneContainerModel = this._addPaneContainerToWorkspace( - rightPaneContainer, - rightDock.dock, - addedItemsByDock, - size, - ); + rightPaneContainer, + rightDock.dock, + addedItemsByDock, + size); + } // Lay out the remaining debugger panes according to their configurations. @@ -696,91 +696,91 @@ export default class DebuggerLayoutManager { // time they were positioned, so we maintain the relative ordering of // debugger panes within the same dock. const mode = this._service.getDebuggerMode(); - this._debuggerPanes - .slice() - .sort((a, b) => { - const aPos = - a.previousLocation == null ? 0 : a.previousLocation.layoutIndex; - const bPos = - b.previousLocation == null ? 0 : b.previousLocation.layoutIndex; - return aPos - bPos; - }) - .filter( - debuggerPane => - (debuggerPane.isEnabled == null || debuggerPane.isEnabled()) && - (debuggerPane.previousLocation == null || - !debuggerPane.previousLocation.userHidden), - ) - .forEach(debuggerPane => { - let targetDock = defaultDock; - - // If this pane had a previous location, restore to the previous dock. - const loc = - debuggerPane.previousLocation != null - ? debuggerPane.previousLocation.dock - : debuggerPane.defaultLocation; - const previousDock = this._getWorkspaceDocks().find( - d => d.name === loc, - ); - if (previousDock != null) { - targetDock = previousDock; - } + this._debuggerPanes. + slice(). + sort((a, b) => { + const aPos = + a.previousLocation == null ? 0 : a.previousLocation.layoutIndex; + const bPos = + b.previousLocation == null ? 0 : b.previousLocation.layoutIndex; + return aPos - bPos; + }). + filter( + debuggerPane => + (debuggerPane.isEnabled == null || debuggerPane.isEnabled()) && ( + debuggerPane.previousLocation == null || + !debuggerPane.previousLocation.userHidden)). + + forEach(debuggerPane => { + let targetDock = defaultDock; + + // If this pane had a previous location, restore to the previous dock. + const loc = + debuggerPane.previousLocation != null ? + debuggerPane.previousLocation.dock : + debuggerPane.defaultLocation; + const previousDock = this._getWorkspaceDocks().find( + d => d.name === loc); + + if (previousDock != null) { + targetDock = previousDock; + } - // Render to a nested pane container for the two vertical docks - // rather than adding the item directly to the dock itself. - let targetContainer = targetDock.dock; - if (targetDock.name === 'left') { - targetContainer = leftPaneContainer; - } else if (targetDock.name === 'right') { - targetContainer = rightPaneContainer; - } + // Render to a nested pane container for the two vertical docks + // rather than adding the item directly to the dock itself. + let targetContainer = targetDock.dock; + if (targetDock.name === 'left') { + targetContainer = leftPaneContainer; + } else if (targetDock.name === 'right') { + targetContainer = rightPaneContainer; + } - if ( - debuggerPane.debuggerModeFilter == null || - debuggerPane.debuggerModeFilter(mode) - ) { - invariant(targetContainer != null); - const size = this._getSavedDebuggerPaneSize(targetDock); - this._appendItemToDock( - debuggerPane, - targetContainer, - new DebuggerPaneViewModel( - debuggerPane, - debuggerPane.isLifetimeView, - pane => this._paneDestroyed(pane), - size, - ), - addedItemsByDock, - ); - } - }); + if ( + debuggerPane.debuggerModeFilter == null || + debuggerPane.debuggerModeFilter(mode)) + {if (!( + targetContainer != null)) {throw new Error('Invariant violation: "targetContainer != null"');} + const size = this._getSavedDebuggerPaneSize(targetDock); + this._appendItemToDock( + debuggerPane, + targetContainer, + new (_DebuggerPaneViewModel || _load_DebuggerPaneViewModel()).default( + debuggerPane, + debuggerPane.isLifetimeView, + pane => this._paneDestroyed(pane), + size), + + addedItemsByDock); + + } + }); this._debuggerVisible = true; } _addPaneContainerToWorkspace( - container: atom$PaneContainer, - dock: atom$AbstractPaneContainer, - addedItemsByDock: Map, - dockSize: ?number, - ): DebuggerPaneContainerViewModel { - const containerModel = new DebuggerPaneContainerViewModel( - container, - dockSize, - ); + container, + dock, + addedItemsByDock, + dockSize) + { + const containerModel = new (_DebuggerPaneContainerViewModel || _load_DebuggerPaneContainerViewModel()).default( + container, + dockSize); + this._appendItemToDock(null, dock, containerModel, addedItemsByDock); return containerModel; } - _paneDestroyed(pane: DebuggerPaneConfig): void { + _paneDestroyed(pane) { if (pane.isLifetimeView) { // Lifetime views are not hidden and remembered like the unimportant views. // This view being destroyed means the debugger is exiting completely, and // this view is never remembered as "hidden by the user" because it's reqiured // for running the debugger. const mode = this._service.getDebuggerMode(); - if (mode === DebuggerMode.RUNNING || mode === DebuggerMode.PAUSED) { + if (mode === (_constants || _load_constants()).DebuggerMode.RUNNING || mode === (_constants || _load_constants()).DebuggerMode.PAUSED) { this._saveDebuggerPaneLocations(); } @@ -791,24 +791,24 @@ export default class DebuggerLayoutManager { // Views can be selectively hidden by the user while the debugger is // running and that preference should be remembered. - const config = this._debuggerPanes.find(p => p.uri === pane.uri); - invariant(config != null); + const config = this._debuggerPanes.find(p => p.uri === pane.uri);if (!( + config != null)) {throw new Error('Invariant violation: "config != null"');} if (config.previousLocation == null) { config.previousLocation = { dock: '', layoutIndex: 0, - userHidden: false, - }; + userHidden: false }; + } if (config.isEnabled == null || config.isEnabled()) { const mode = this._service.getDebuggerMode(); if ( - config.debuggerModeFilter == null || - config.debuggerModeFilter(mode) - ) { - invariant(config.previousLocation != null); + config.debuggerModeFilter == null || + config.debuggerModeFilter(mode)) + {if (!( + config.previousLocation != null)) {throw new Error('Invariant violation: "config.previousLocation != null"');} config.previousLocation.userHidden = true; // Show a notification telling the user how to get the pane back @@ -817,8 +817,8 @@ export default class DebuggerLayoutManager { this._paneHiddenWarningShown = true; atom.notifications.addInfo( - `${config.title()} has been hidden. Right click any Debugger pane to bring it back.`, - ); + `${config.title()} has been hidden. Right click any Debugger pane to bring it back.`); + } } } @@ -828,7 +828,7 @@ export default class DebuggerLayoutManager { this._destroyContainerIfEmpty(this._rightPaneContainerModel); } - _destroyContainerIfEmpty(container: ?DebuggerPaneContainerViewModel): void { + _destroyContainerIfEmpty(container) { if (container != null && container.getAllItems().length === 0) { const parent = container.getParentPane(); if (parent != null) { @@ -838,7 +838,7 @@ export default class DebuggerLayoutManager { } } - hideDebuggerViews(performingLayout: boolean): void { + hideDebuggerViews(performingLayout) { // Docks do not toggle closed automatically when we remove all their items. // They can contain things other than the debugger items though, and could // have been left open and empty by the user. Toggle closed any docks that @@ -850,9 +850,9 @@ export default class DebuggerLayoutManager { atom.workspace.getPanes().forEach(pane => { pane.getItems().forEach(item => { if ( - item instanceof DebuggerPaneViewModel || - item instanceof DebuggerPaneContainerViewModel - ) { + item instanceof (_DebuggerPaneViewModel || _load_DebuggerPaneViewModel()).default || + item instanceof (_DebuggerPaneContainerViewModel || _load_DebuggerPaneContainerViewModel()).default) + { // Remove the view model. item.setRemovedFromLayout(true); pane.destroyItem(item); @@ -867,25 +867,25 @@ export default class DebuggerLayoutManager { // If any docks became empty as a result of closing those panes, hide the dock. if (!performingLayout) { - docks - .map(dock => this._isDockEmpty(dock.dock)) - .forEach((empty, index) => { - if (empty && !previouslyEmpty[index]) { - docks[index].dock.hide(); - } - }); + docks. + map(dock => this._isDockEmpty(dock.dock)). + forEach((empty, index) => { + if (empty && !previouslyEmpty[index]) { + docks[index].dock.hide(); + } + }); } if (this._leftPaneContainerModel != null) { - this._leftPaneContainerModel.setRemovedFromLayout(true); - invariant(this._leftPaneContainerModel != null); + this._leftPaneContainerModel.setRemovedFromLayout(true);if (!( + this._leftPaneContainerModel != null)) {throw new Error('Invariant violation: "this._leftPaneContainerModel != null"');} this._leftPaneContainerModel.dispose(); this._leftPaneContainerModel = null; } if (this._rightPaneContainerModel != null) { - this._rightPaneContainerModel.setRemovedFromLayout(true); - invariant(this._rightPaneContainerModel != null); + this._rightPaneContainerModel.setRemovedFromLayout(true);if (!( + this._rightPaneContainerModel != null)) {throw new Error('Invariant violation: "this._rightPaneContainerModel != null"');} this._rightPaneContainerModel.dispose(); this._rightPaneContainerModel = null; } @@ -893,14 +893,23 @@ export default class DebuggerLayoutManager { this._debuggerVisible = false; } - isDebuggerVisible(): boolean { + isDebuggerVisible() { return this._debuggerVisible; } - getWorkspaceDocksVisibility(): Array { + getWorkspaceDocksVisibility() { this._saveDebuggerPaneLocations(); return this._getWorkspaceDocks().map(dock => { return dock.dock.isVisible != null && dock.dock.isVisible(); }); - } -} + }}exports.default = DebuggerLayoutManager; /** + * 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. + * + * + * @format + */ /* global localStorage */ \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerPaneContainerViewModel.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerPaneContainerViewModel.js index 8ef73020..468124c7 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerPaneContainerViewModel.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerPaneContainerViewModel.js @@ -1,37 +1,37 @@ -/** - * 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 - * @format - */ - -import { - DEBUGGER_PANELS_DEFAULT_WIDTH_PX, - DEBUGGER_PANELS_DEFAULT_LOCATION, -} from '../constants'; -import DebuggerPaneViewModel from './DebuggerPaneViewModel'; -import invariant from 'assert'; -import * as React from 'react'; -import TabBarView from 'nuclide-commons-ui/VendorLib/atom-tabs/lib/tab-bar-view'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {View} from 'nuclide-commons-ui/View'; - -const DEBUGGER_TAB_TITLE = 'Debugger'; - -export default class DebuggerPaneContainerViewModel { - _container: atom$PaneContainer; - _disposables: UniversalDisposable; - _paneEvents: Map; - _removedFromLayout: boolean; - _preferredWidth: ?number; - - constructor(paneContainer: atom$PaneContainer, preferredWidth: ?number) { - this._disposables = new UniversalDisposable(); +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _constants; + + + + + + + + + + + +function _load_constants() {return _constants = require('../constants');}var _DebuggerPaneViewModel; + + + +function _load_DebuggerPaneViewModel() {return _DebuggerPaneViewModel = _interopRequireDefault(require('./DebuggerPaneViewModel'));} + +var _react = _interopRequireWildcard(require('react'));var _tabBarView; +function _load_tabBarView() {return _tabBarView = _interopRequireDefault(require('nuclide-commons-ui/VendorLib/atom-tabs/lib/tab-bar-view'));}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _View; +function _load_View() {return _View = require('nuclide-commons-ui/View');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */const DEBUGGER_TAB_TITLE = 'Debugger';class DebuggerPaneContainerViewModel { + constructor(paneContainer, preferredWidth) { + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._paneEvents = new Map(); this._removedFromLayout = false; this._container = paneContainer; @@ -43,69 +43,69 @@ export default class DebuggerPaneContainerViewModel { } this._disposables.add( - () => { - this._forEachChildPaneItem((item: atom$PaneItem) => { - invariant( - item instanceof DebuggerPaneViewModel || - item instanceof DebuggerPaneContainerViewModel, - ); - item.setRemovedFromLayout(this._removedFromLayout); - item.destroy(); - }); - this._container.destroy(); - }, - paneContainer.onDidAddPane(event => { - const pane = event.pane; - - this._kickOutNonDebuggerItems(pane); - if (this._container.getPanes().indexOf(pane) < 0) { - return; - } + () => { + this._forEachChildPaneItem(item => {if (!( - if (!this._conditionallyAddTabBarToPane(pane)) { - // Wait until the item(s) are added to the pane, and then add a tab bar - // above them if and only if the item's title is not the same as the - // container tabs title (we don't want duplicate tabs right beneath each other). - this._deferredAddTabBarToEmptyPane(pane); - } + item instanceof (_DebuggerPaneViewModel || _load_DebuggerPaneViewModel()).default || + item instanceof DebuggerPaneContainerViewModel)) {throw new Error('Invariant violation: "item instanceof DebuggerPaneViewModel ||\\n item instanceof DebuggerPaneContainerViewModel"');} - this._addManagedPane(pane); - }), - paneContainer.onWillDestroyPane(event => { - const disposables = this._paneEvents.get(event.pane); - if (disposables != null) { - disposables.dispose(); - this._paneEvents.delete(event.pane); - } - }), - paneContainer.onDidDestroyPane(event => { - // If this container is now empty, destroy it! - const panes = this._container.getPanes(); - if ( - panes.length === 0 || - (panes.length === 1 && panes[0].getItems().length === 0) - ) { - const parent = this.getParentPane(); - if (parent != null) { - parent.removeItem(this); - } + item.setRemovedFromLayout(this._removedFromLayout); + item.destroy(); + }); + this._container.destroy(); + }, + paneContainer.onDidAddPane(event => { + const pane = event.pane; + + this._kickOutNonDebuggerItems(pane); + if (this._container.getPanes().indexOf(pane) < 0) { + return; + } + + if (!this._conditionallyAddTabBarToPane(pane)) { + // Wait until the item(s) are added to the pane, and then add a tab bar + // above them if and only if the item's title is not the same as the + // container tabs title (we don't want duplicate tabs right beneath each other). + this._deferredAddTabBarToEmptyPane(pane); + } + + this._addManagedPane(pane); + }), + paneContainer.onWillDestroyPane(event => { + const disposables = this._paneEvents.get(event.pane); + if (disposables != null) { + disposables.dispose(); + this._paneEvents.delete(event.pane); + } + }), + paneContainer.onDidDestroyPane(event => { + // If this container is now empty, destroy it! + const panes = this._container.getPanes(); + if ( + panes.length === 0 || + panes.length === 1 && panes[0].getItems().length === 0) + { + const parent = this.getParentPane(); + if (parent != null) { + parent.removeItem(this); } - }), - ); + } + })); + } - _addManagedPane(pane: atom$Pane): void { + _addManagedPane(pane) { let disposables = this._paneEvents.get(pane); if (disposables == null) { - disposables = new UniversalDisposable(); + disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this._paneEvents.set(pane, disposables); } disposables.add( - pane.onDidAddItem(event => { - this._kickOutNonDebuggerItems(pane); - }), - ); + pane.onDidAddItem(event => { + this._kickOutNonDebuggerItems(pane); + })); + // Split operations on the child panes of this container are also being // executed on the parent pane that contains this container, which results @@ -119,24 +119,24 @@ export default class DebuggerPaneContainerViewModel { // If a pane is initially empty, don't add the tab bar until the first item // is added to the pane, otherwise we don't know what title to give the tab! - _deferredAddTabBarToEmptyPane(pane: atom$Pane): void { - const pendingAddTabDisposable = new UniversalDisposable(); + _deferredAddTabBarToEmptyPane(pane) { + const pendingAddTabDisposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(); pendingAddTabDisposable.add( - pane.onDidAddItem(event => { - if (this._conditionallyAddTabBarToPane(pane)) { - this._disposables.remove(pendingAddTabDisposable); - pendingAddTabDisposable.dispose(); - } - }), - ); + pane.onDidAddItem(event => { + if (this._conditionallyAddTabBarToPane(pane)) { + this._disposables.remove(pendingAddTabDisposable); + pendingAddTabDisposable.dispose(); + } + })); + this._disposables.add(pendingAddTabDisposable); } - _conditionallyAddTabBarToPane(pane: atom$Pane): boolean { + _conditionallyAddTabBarToPane(pane) { const items = pane.getItems(); if (items.length > 0) { const item = items[0]; - if (item instanceof DebuggerPaneViewModel) { + if (item instanceof (_DebuggerPaneViewModel || _load_DebuggerPaneViewModel()).default) { if (item.getTitle() !== this.getTitle() || items.length > 1) { this._addTabBarToPane(pane); return true; @@ -150,7 +150,7 @@ export default class DebuggerPaneContainerViewModel { // Don't let the user add a non-debugger item to the debugger pane container. This is because // the container will get destroyed by the debugger going away or redoing layout, and we wouldn't // be able to preserve the user's other items. - _kickOutNonDebuggerItems(pane: atom$Pane): void { + _kickOutNonDebuggerItems(pane) { for (const item of pane.getItems()) { if (item instanceof DebuggerPaneContainerViewModel) { if (item === this) { @@ -160,9 +160,9 @@ export default class DebuggerPaneContainerViewModel { // TODO: Better solution here. process.nextTick(() => { atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'debugger:show', - ); + atom.views.getView(atom.workspace), + 'debugger:show'); + }); } else { // This is another debugger pane container, which contains other debugger @@ -184,38 +184,38 @@ export default class DebuggerPaneContainerViewModel { } } else { // Kick the item out to the parent pane. - if (!(item instanceof DebuggerPaneViewModel)) { + if (!(item instanceof (_DebuggerPaneViewModel || _load_DebuggerPaneViewModel()).default)) { this._moveItemToParentPane(item, pane); } } } } - _moveItemToParentPane(item: atom$PaneItem, pane: atom$Pane): void { - const parentPane = this.getParentPane(); - invariant(parentPane != null); + _moveItemToParentPane(item, pane) { + const parentPane = this.getParentPane();if (!( + parentPane != null)) {throw new Error('Invariant violation: "parentPane != null"');} // Kick the item out to the parent pane, which must be done on next tick because the drag // operation currently in progress needs the item not to be destroyed before the drag // completes. - process.nextTick(() => { - invariant(parentPane != null); + process.nextTick(() => {if (!( + parentPane != null)) {throw new Error('Invariant violation: "parentPane != null"');} pane.moveItemToPane( - item, - parentPane, - parentPane.getItems().indexOf(this) + 1, - ); + item, + parentPane, + parentPane.getItems().indexOf(this) + 1); + // TODO: Atom bug? This is here because when setting this item active immediately after // moving, it sometimes (but not always) renders a blank pane... - process.nextTick(() => { - invariant(parentPane != null); + process.nextTick(() => {if (!( + parentPane != null)) {throw new Error('Invariant violation: "parentPane != null"');} parentPane.setActiveItem(item); }); }); } - getParentPane(): ?atom$Pane { + getParentPane() { for (const pane of atom.workspace.getPanes()) { for (const item of pane.getItems()) { if (item === this) { @@ -226,8 +226,8 @@ export default class DebuggerPaneContainerViewModel { return null; } - _addTabBarToPane(pane: atom$Pane): void { - const tabBarView = new TabBarView(pane); + _addTabBarToPane(pane) { + const tabBarView = new (_tabBarView || _load_tabBarView()).default(pane); const paneElement = atom.views.getView(pane); paneElement.insertBefore(tabBarView.element, paneElement.firstChild); @@ -235,15 +235,15 @@ export default class DebuggerPaneContainerViewModel { // Empty it out to get the correct behavior. tabBarView.moveItemBetweenPanes = () => {}; tabBarView.element.classList.add( - 'nuclide-workspace-views-panel-location-tabs', - ); + 'nuclide-workspace-views-panel-location-tabs'); + } - dispose(): void { + dispose() { this._disposables.dispose(); } - destroy(): void { + destroy() { if (!this._removedFromLayout) { // We need to differentiate between the case where destroying this pane hides one or more // non-essential debugger views, and where it means the user is closing the debugger. @@ -253,7 +253,7 @@ export default class DebuggerPaneContainerViewModel { // contained within this pane, which is accomplished by disposing this. for (const pane of this._container.getPanes()) { for (const item of pane.getItems()) { - if (item instanceof DebuggerPaneViewModel) { + if (item instanceof (_DebuggerPaneViewModel || _load_DebuggerPaneViewModel()).default) { if (item.isLifetimeView()) { item.destroy(); return; @@ -266,7 +266,7 @@ export default class DebuggerPaneContainerViewModel { this.dispose(); } - destroyWhere(callback: (item: atom$PaneItem) => mixed) { + destroyWhere(callback) { this._forEachChildPaneItem((innerItem, pane) => { if (callback(innerItem)) { pane.destroyItem(innerItem); @@ -274,46 +274,46 @@ export default class DebuggerPaneContainerViewModel { }); } - getTitle(): string { + getTitle() { return DEBUGGER_TAB_TITLE; } - getIconName(): string { + getIconName() { return 'nuclicon-debugger'; } - getDefaultLocation(): string { - return DEBUGGER_PANELS_DEFAULT_LOCATION; + getDefaultLocation() { + return (_constants || _load_constants()).DEBUGGER_PANELS_DEFAULT_LOCATION; } - getURI(): string { + getURI() { return 'atom://nuclide/debugger-container'; } - getPreferredWidth(): number { - return this._preferredWidth == null - ? DEBUGGER_PANELS_DEFAULT_WIDTH_PX - : this._preferredWidth; + getPreferredWidth() { + return this._preferredWidth == null ? (_constants || _load_constants()).DEBUGGER_PANELS_DEFAULT_WIDTH_PX : + + this._preferredWidth; } - createView(): React.Element { - return ; + createView() { + return _react.createElement((_View || _load_View()).View, { item: this._container }); } - setRemovedFromLayout(removed: boolean): void { + setRemovedFromLayout(removed) { this._removedFromLayout = removed; // Propagate this command to the children of the pane container. this._forEachChildPaneItem(item => { - if (item instanceof DebuggerPaneViewModel) { + if (item instanceof (_DebuggerPaneViewModel || _load_DebuggerPaneViewModel()).default) { item.setRemovedFromLayout(removed); } }); } _forEachChildPaneItem( - callback: (item: atom$PaneItem, pane: atom$Pane) => void, - ): void { + callback) + { for (const pane of this._container.getPanes()) { pane.getItems().forEach(item => { callback(item, pane); @@ -321,7 +321,7 @@ export default class DebuggerPaneContainerViewModel { } } - getAllItems(): Array { + getAllItems() { const items = []; this._forEachChildPaneItem(item => { items.push(item); @@ -330,11 +330,10 @@ export default class DebuggerPaneContainerViewModel { return items; } - serialize(): Object { + serialize() { return {}; } - copy(): boolean { + copy() { return false; - } -} + }}exports.default = DebuggerPaneContainerViewModel; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerPaneViewModel.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerPaneViewModel.js index e40184ef..8932a245 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerPaneViewModel.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerPaneViewModel.js @@ -1,40 +1,40 @@ -/** - * 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 - * @format - */ - -import type {DebuggerPaneConfig} from './DebuggerLayoutManager'; -import * as React from 'react'; -import { - DEBUGGER_PANELS_DEFAULT_WIDTH_PX, - DEBUGGER_PANELS_DEFAULT_LOCATION, -} from '../constants'; +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); + + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react'));var _constants; +function _load_constants() {return _constants = require('../constants');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} + + + // A model that will serve as the view model for all debugger panes. We must provide // a unique instance of a view model for each pane, which Atom can destroy when the // pane that contains it is destroyed. We therefore cannot give it the actual debugger // model directly, since there is only one and its lifetime is tied to the lifetime // of the debugging session. -export default class DebuggerPaneViewModel { - _config: DebuggerPaneConfig; - _isLifetimeView: boolean; - _paneDestroyed: (pane: DebuggerPaneConfig) => void; - _removedFromLayout: boolean; - _preferredWidth: ?number; +class DebuggerPaneViewModel { + + + + + constructor( - config: DebuggerPaneConfig, - isLifetimeView: boolean, - paneDestroyed: (pane: DebuggerPaneConfig) => void, - preferredWidth: ?number, - ) { + config, + isLifetimeView, + paneDestroyed, + preferredWidth) + { this._config = config; this._isLifetimeView = isLifetimeView; this._paneDestroyed = paneDestroyed; @@ -42,57 +42,66 @@ export default class DebuggerPaneViewModel { this._preferredWidth = preferredWidth; } - dispose(): void {} + dispose() {} - destroy(): void { + destroy() { if (!this._removedFromLayout) { this._paneDestroyed(this._config); } } - getTitle(): string { + getTitle() { return this._config.title(); } - getDefaultLocation(): string { - return DEBUGGER_PANELS_DEFAULT_LOCATION; + getDefaultLocation() { + return (_constants || _load_constants()).DEBUGGER_PANELS_DEFAULT_LOCATION; } - getURI(): string { + getURI() { return this._config.uri; } - getPreferredWidth(): number { - return this._preferredWidth == null - ? DEBUGGER_PANELS_DEFAULT_WIDTH_PX - : this._preferredWidth; + getPreferredWidth() { + return this._preferredWidth == null ? (_constants || _load_constants()).DEBUGGER_PANELS_DEFAULT_WIDTH_PX : + + this._preferredWidth; } - createView(): React.Element { + createView() { if (this._config.previousLocation != null) { this._config.previousLocation.userHidden = false; } return this._config.createView(); } - getConfig(): DebuggerPaneConfig { + getConfig() { return this._config; } - isLifetimeView(): boolean { + isLifetimeView() { return this._isLifetimeView; } - setRemovedFromLayout(removed: boolean): void { + setRemovedFromLayout(removed) { this._removedFromLayout = removed; } // Atom view needs to provide this, otherwise Atom throws an exception splitting panes for the view. - serialize(): Object { + serialize() { return {}; } - copy(): boolean { + copy() { return false; - } -} + }}exports.default = DebuggerPaneViewModel; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerSteppingComponent.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerSteppingComponent.js index 559bbf3c..34810e92 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerSteppingComponent.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/DebuggerSteppingComponent.js @@ -1,238 +1,238 @@ -/** - * 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 - * @format - */ - -import type {DebuggerModeType, IDebugService, IThread} from '../types'; -import type {ControlButtonSpecification} from 'nuclide-debugger-common'; -import { - LoadingSpinner, - LoadingSpinnerSizes, -} from 'nuclide-commons-ui/LoadingSpinner'; - -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import {fastDebounce} from 'nuclide-commons/observable'; -import * as React from 'react'; -import {Button} from 'nuclide-commons-ui/Button'; -import {ButtonGroup} from 'nuclide-commons-ui/ButtonGroup'; -import {Observable} from 'rxjs'; -import {DebuggerMode} from '../constants'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import logger from '../logger'; -import nullthrows from 'nullthrows'; - -type DebuggerSteppingComponentProps = { - service: IDebugService, -}; - -type DebuggerSteppingComponentState = { - debuggerMode: DebuggerModeType, - waitingForPause: boolean, - customControlButtons: Array, -}; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _LoadingSpinner; + + + + + + + + + + + + + +function _load_LoadingSpinner() {return _LoadingSpinner = require('nuclide-commons-ui/LoadingSpinner');}var _event; + + + + +function _load_event() {return _event = require('nuclide-commons/event');}var _observable; +function _load_observable() {return _observable = require('nuclide-commons/observable');} +var _react = _interopRequireWildcard(require('react'));var _Button; +function _load_Button() {return _Button = require('nuclide-commons-ui/Button');}var _ButtonGroup; +function _load_ButtonGroup() {return _ButtonGroup = require('nuclide-commons-ui/ButtonGroup');} +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _constants; +function _load_constants() {return _constants = require('../constants');}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _logger; +function _load_logger() {return _logger = _interopRequireDefault(require('../logger'));}var _nullthrows; +function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} + + + + + + + + + + const defaultTooltipOptions = { - placement: 'bottom', -}; - -const STEP_OVER_ICON = ( - - - - -); - -const STEP_INTO_ICON = ( - - - - -); - -const STEP_OUT_ICON = ( - - - - -); - -function SVGButton(props: { - onClick: () => mixed, - tooltip: atom$TooltipsAddOptions, - icon: React.Element, - disabled: boolean, -}): React.Element { + placement: 'bottom' }; /** + * 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. + * + * + * @format + */const STEP_OVER_ICON = _react.createElement('svg', { viewBox: '0 0 100 100' }, _react.createElement('circle', { cx: '46', cy: '63', r: '10' }), _react.createElement('path', { d: 'M83.8,54.7c-6.5-16.6-20.7-28.1-37.2-28.1c-19.4,0-35.6,16-39.9,' + '37.3l11.6,2.9c3-16.2,14.5-28.2,28.2-28.2 c11,0,20.7,7.8,25.6,' + '19.3l-9.6,2.7l20.8,14.7L93.7,52L83.8,54.7z' })); + + + + + +const STEP_INTO_ICON = +_react.createElement('svg', { viewBox: '0 0 100 100' }, + _react.createElement('circle', { cx: '50', cy: '75', r: '10' }), + _react.createElement('polygon', { points: '42,20 57,20 57,40 72,40 50,60 28,40 42,40' })); + + + +const STEP_OUT_ICON = +_react.createElement('svg', { viewBox: '0 0 100 100' }, + _react.createElement('circle', { cx: '50', cy: '75', r: '10' }), + _react.createElement('polygon', { + points: '42,20 57,20 57,40 72,40 50,60 28,40 42,40', + transform: 'rotate(180, 50, 40)' })); + + + + +function SVGButton(props) + + + + +{ return ( - - ); + _react.createElement((_Button || _load_Button()).Button, { + className: 'debugger-stepping-svg-button', + onClick: props.onClick, + disabled: props.disabled, + tooltip: props.tooltip }, + _react.createElement('div', null, props.icon))); + + } -export default class DebuggerSteppingComponent extends React.Component< - DebuggerSteppingComponentProps, - DebuggerSteppingComponentState, -> { - _disposables: UniversalDisposable; - - constructor(props: DebuggerSteppingComponentProps) { - super(props); - - this._disposables = new UniversalDisposable(); - const {service} = props; - this.state = { - debuggerMode: service.getDebuggerMode(), - waitingForPause: false, - customControlButtons: [], - }; - } - - componentDidMount(): void { - const {service} = this.props; - const model = service.getModel(); - this._disposables.add( - Observable.merge( - observableFromSubscribeFunction(service.onDidChangeMode.bind(service)), - observableFromSubscribeFunction(model.onDidChangeCallStack.bind(model)), - observableFromSubscribeFunction( - service.viewModel.onDidFocusStackFrame.bind(service.viewModel), - ), - ) - .startWith(null) - .let(fastDebounce(10)) - .subscribe(() => { - const debuggerMode = service.getDebuggerMode(); - const {focusedProcess} = service.viewModel; - - this.setState({ - debuggerMode, - customControlButtons: - focusedProcess == null - ? [] - : focusedProcess.configuration.properties.customControlButtons, - }); - if ( - this.state.waitingForPause && - debuggerMode !== DebuggerMode.RUNNING - ) { - this._setWaitingForPause(false); - } - }), - ); - } - - componentWillUnmount(): void { - this._disposables.dispose(); - } - - _setWaitingForPause(waiting: boolean): void { - this.setState({ - waitingForPause: waiting, - }); - } - - _getPausableThread(): ?IThread { - const {focusedThread, focusedProcess} = this.props.service.viewModel; - if (focusedThread != null) { - return focusedThread; - } else if (focusedProcess != null) { - return focusedProcess.getAllThreads()[0]; - } else { - return null; - } - } +class DebuggerSteppingComponent extends _react.Component + + +{ + + + constructor(props) { + super(props);this. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _togglePauseState = () => { + const pausableThread = this._getPausableThread(); + if (pausableThread == null) { + (_logger || _load_logger()).default.error('No thread to pause/resume'); + return; + } + + if (pausableThread.stopped) { + pausableThread.continue(); + } else { + this._setWaitingForPause(true); + pausableThread.pause(); + } + };this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default();const { service } = props;this.state = { debuggerMode: service.getDebuggerMode(), waitingForPause: false, customControlButtons: [] };}componentDidMount() {const { service } = this.props;const model = service.getModel();this._disposables.add(_rxjsBundlesRxMinJs.Observable.merge((0, (_event || _load_event()).observableFromSubscribeFunction)(service.onDidChangeMode.bind(service)), (0, (_event || _load_event()).observableFromSubscribeFunction)(model.onDidChangeCallStack.bind(model)), (0, (_event || _load_event()).observableFromSubscribeFunction)(service.viewModel.onDidFocusStackFrame.bind(service.viewModel))).startWith(null).let((0, (_observable || _load_observable()).fastDebounce)(10)).subscribe(() => {const debuggerMode = service.getDebuggerMode();const { focusedProcess } = service.viewModel;this.setState({ debuggerMode, customControlButtons: focusedProcess == null ? [] : focusedProcess.configuration.properties.customControlButtons });if (this.state.waitingForPause && debuggerMode !== (_constants || _load_constants()).DebuggerMode.RUNNING) {this._setWaitingForPause(false);}}));}componentWillUnmount() {this._disposables.dispose();}_setWaitingForPause(waiting) {this.setState({ waitingForPause: waiting });}_getPausableThread() {const { focusedThread, focusedProcess } = this.props.service.viewModel;if (focusedThread != null) {return focusedThread;} else if (focusedProcess != null) {return focusedProcess.getAllThreads()[0];} else {return null;}} + + render() { + const { debuggerMode, waitingForPause, customControlButtons } = this.state; + const { service } = this.props; + const { focusedThread } = service.viewModel; + const isPaused = debuggerMode === (_constants || _load_constants()).DebuggerMode.PAUSED; + const isStopped = debuggerMode === (_constants || _load_constants()).DebuggerMode.STOPPED; + const isPausing = debuggerMode === (_constants || _load_constants()).DebuggerMode.RUNNING && waitingForPause; + const playPauseIcon = isPausing ? null : + _react.createElement('span', { + className: isPaused ? 'icon-playback-play' : 'icon-playback-pause' }); + + + + const loadingIndicator = !isPausing ? null : + _react.createElement((_LoadingSpinner || _load_LoadingSpinner()).LoadingSpinner, { + className: 'debugger-stepping-playpause-button-loading', + size: (_LoadingSpinner || _load_LoadingSpinner()).LoadingSpinnerSizes.EXTRA_SMALL }); - _togglePauseState = () => { - const pausableThread = this._getPausableThread(); - if (pausableThread == null) { - logger.error('No thread to pause/resume'); - return; - } - if (pausableThread.stopped) { - pausableThread.continue(); - } else { - this._setWaitingForPause(true); - pausableThread.pause(); - } - }; - - render(): React.Node { - const {debuggerMode, waitingForPause, customControlButtons} = this.state; - const {service} = this.props; - const {focusedThread} = service.viewModel; - const isPaused = debuggerMode === DebuggerMode.PAUSED; - const isStopped = debuggerMode === DebuggerMode.STOPPED; - const isPausing = debuggerMode === DebuggerMode.RUNNING && waitingForPause; - const playPauseIcon = isPausing ? null : ( - - ); - - const loadingIndicator = !isPausing ? null : ( - - ); const restartDebuggerButton = - debuggerMode !== DebuggerMode.STOPPED ? ( - - nullthrows(focusedThread).next()} - /> - nullthrows(focusedThread).stepIn()} - /> - nullthrows(focusedThread).stepOut()} - /> -
cellData.stopped} - resizable={true} - onSelect={this._handleSelectThread} - sortable={true} - onSort={this._handleSort} - sortedColumn={this.state.sortedColumn} - sortDescending={this.state.sortDescending} - ref={table => { + _react.createElement((_Table || _load_Table()).Table, { + columns: columns, + emptyComponent: emptyComponent, + rows: this._sortRows( + rows, + this.state.sortedColumn, + this.state.sortDescending), + + selectable: cellData => cellData.stopped, + resizable: true, + onSelect: this._handleSelectThread, + sortable: true, + onSort: this._handleSort, + sortedColumn: this.state.sortedColumn, + sortDescending: this.state.sortDescending, + ref: table => { this._threadTable = table; - }} - /> - ); - } -} + } })); + + + }}exports.default = DebuggerThreadsComponent; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/ScopesComponent.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/ScopesComponent.js index dededa2a..f835365a 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/ScopesComponent.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/ScopesComponent.js @@ -1,173 +1,173 @@ -/** - * 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 - * @format - */ - -import type {IDebugService, IScope, IVariable} from '../types'; -import type {Expected} from 'nuclide-commons/expected'; - -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import * as React from 'react'; -import {LazyNestedValueComponent} from 'nuclide-commons-ui/LazyNestedValueComponent'; -import SimpleValueComponent from 'nuclide-commons-ui/SimpleValueComponent'; -import invariant from 'assert'; -import {Observable} from 'rxjs'; -import {Section} from 'nuclide-commons-ui/Section'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import { - fetchChildrenForLazyComponent, - expressionAsEvaluationResult, -} from '../utils'; -import {Expect} from 'nuclide-commons/expected'; -import {LoadingSpinner} from 'nuclide-commons-ui/LoadingSpinner'; - -type Props = {| - +service: IDebugService, -|}; - -const NO_VARIABLES = ( -
- (no variables) -
-); - -const LOADING = ( -
- - - -
-); - -type State = {| - scopes: Expected>, - expandedScopes: Set, -|}; - -export default class ScopesComponent extends React.Component { - _disposables: UniversalDisposable; - _expansionStates: Map< - string /* expression */, - Object /* unique reference for expression */, - >; - - constructor(props: Props) { - super(props); - this.state = { - scopes: Expect.value([]), - // UX: Local scope names should be expanded by default. - expandedScopes: new Set(['Local', 'Locals']), - }; - this._expansionStates = new Map(); - this._disposables = new UniversalDisposable(); - } +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _bindObservableAsProps; - componentDidMount(): void { - const {viewModel} = this.props.service; - this._disposables.add( - Observable.merge( - observableFromSubscribeFunction( - viewModel.onDidFocusStackFrame.bind(viewModel), - ), - observableFromSubscribeFunction( - viewModel.onDidChangeExpressionContext.bind(viewModel), - ), - ) - .debounceTime(100) - .switchMap(() => this._getScopes()) - .subscribe(scopes => { - this.setState({scopes}); - }), - ); - } - _getScopes(): Observable>> { - const {focusedStackFrame} = this.props.service.viewModel; - if (focusedStackFrame == null) { - return Observable.of(Expect.value([])); - } else { - return Observable.of(Expect.pendingValue([])).concat( - Observable.fromPromise( - focusedStackFrame - .getScopes() - .then(scopes => Expect.value(scopes), error => Expect.error(error)), - ), - ); - } - } - componentWillUnmount(): void { - this._disposables.dispose(); - } - _renderScopeSection(scope: IScope): ?React.Element { - // Non-local scopes should be collapsed by default since users typically care less about them. - const expanded = this._isScopeExpanded(scope); - const {focusedProcess} = this.props.service.viewModel; - const canSetVariables = - focusedProcess != null && - focusedProcess.session.capabilities.supportsSetVariable; - let ScopeBodyComponent = () => null; - if (expanded) { - ScopeBodyComponent = bindObservableAsProps( - this._getScopeVariables(scope).map(variables => ({ - variables, - canSetVariables, - getExpansionStateIdForExpression: this - ._getExpansionStateIdForExpression, - })), - ScopeComponent, - ); - } - return ( -
this._setScopeExpanded(scope, !isCollapsed)} - headline={scope.name} - size="small"> - -
- ); - } - _getExpansionStateIdForExpression = (expression: string): Object => { - let expansionStateId = this._expansionStates.get(expression); - if (expansionStateId == null) { - expansionStateId = {}; - this._expansionStates.set(expression, expansionStateId); - } - return expansionStateId; - }; - - _getScopeVariables(scope: IScope): Observable>> { - return Observable.of(Expect.pendingValue([])).concat( - Observable.fromPromise( - scope - .getChildren() - .then( - variables => Expect.value(variables), - error => Expect.error(error), - ), - ), - ); + + + + + + + + +function _load_bindObservableAsProps() {return _bindObservableAsProps = require('nuclide-commons-ui/bindObservableAsProps');} +var _react = _interopRequireWildcard(require('react'));var _LazyNestedValueComponent; +function _load_LazyNestedValueComponent() {return _LazyNestedValueComponent = require('nuclide-commons-ui/LazyNestedValueComponent');}var _SimpleValueComponent; +function _load_SimpleValueComponent() {return _SimpleValueComponent = _interopRequireDefault(require('nuclide-commons-ui/SimpleValueComponent'));} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _Section; +function _load_Section() {return _Section = require('nuclide-commons-ui/Section');}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _event; +function _load_event() {return _event = require('nuclide-commons/event');}var _utils; +function _load_utils() {return _utils = require('../utils');}var _expected; + + + +function _load_expected() {return _expected = require('nuclide-commons/expected');}var _LoadingSpinner; +function _load_LoadingSpinner() {return _LoadingSpinner = require('nuclide-commons-ui/LoadingSpinner');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} + + + + + +const NO_VARIABLES = +_react.createElement('div', { className: 'debugger-expression-value-row' }, + _react.createElement('span', { className: 'debugger-expression-value-content' }, '(no variables)')); /** + * 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. + * + * + * @format + */const LOADING = _react.createElement('div', { className: 'debugger-expression-value-row' }, _react.createElement('span', { className: 'debugger-expression-value-content' }, _react.createElement((_LoadingSpinner || _load_LoadingSpinner()).LoadingSpinner, { size: 'MEDIUM' }))); + + + + + + +class ScopesComponent extends _react.Component { + + + + + + + constructor(props) { + super(props);this. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _getExpansionStateIdForExpression = expression => { + let expansionStateId = this._expansionStates.get(expression); + if (expansionStateId == null) { + expansionStateId = {}; + this._expansionStates.set(expression, expansionStateId); + } + return expansionStateId; + };this.state = { scopes: (_expected || _load_expected()).Expect.value([]), // UX: Local scope names should be expanded by default. + expandedScopes: new Set(['Local', 'Locals']) };this._expansionStates = new Map();this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default();}componentDidMount() {const { viewModel } = this.props.service;this._disposables.add(_rxjsBundlesRxMinJs.Observable.merge((0, (_event || _load_event()).observableFromSubscribeFunction)(viewModel.onDidFocusStackFrame.bind(viewModel)), (0, (_event || _load_event()).observableFromSubscribeFunction)(viewModel.onDidChangeExpressionContext.bind(viewModel))).debounceTime(100).switchMap(() => this._getScopes()).subscribe(scopes => {this.setState({ scopes });}));}_getScopes() {const { focusedStackFrame } = this.props.service.viewModel;if (focusedStackFrame == null) {return _rxjsBundlesRxMinJs.Observable.of((_expected || _load_expected()).Expect.value([]));} else {return _rxjsBundlesRxMinJs.Observable.of((_expected || _load_expected()).Expect.pendingValue([])).concat(_rxjsBundlesRxMinJs.Observable.fromPromise(focusedStackFrame.getScopes().then(scopes => (_expected || _load_expected()).Expect.value(scopes), error => (_expected || _load_expected()).Expect.error(error))));}}componentWillUnmount() {this._disposables.dispose();}_renderScopeSection(scope) {// Non-local scopes should be collapsed by default since users typically care less about them. + const expanded = this._isScopeExpanded(scope);const { focusedProcess } = this.props.service.viewModel;const canSetVariables = focusedProcess != null && focusedProcess.session.capabilities.supportsSetVariable;let ScopeBodyComponent = () => null;if (expanded) {ScopeBodyComponent = (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)(this._getScopeVariables(scope).map(variables => ({ variables, canSetVariables, getExpansionStateIdForExpression: this._getExpansionStateIdForExpression })), ScopeComponent);}return _react.createElement((_Section || _load_Section()).Section, { key: scope.getId(), collapsable: true, collapsed: !expanded, onChange: isCollapsed => this._setScopeExpanded(scope, !isCollapsed), headline: scope.name, size: 'small' }, _react.createElement(ScopeBodyComponent, null));}_getScopeVariables(scope) { + return _rxjsBundlesRxMinJs.Observable.of((_expected || _load_expected()).Expect.pendingValue([])).concat( + _rxjsBundlesRxMinJs.Observable.fromPromise( + scope. + getChildren(). + then( + variables => (_expected || _load_expected()).Expect.value(variables), + error => (_expected || _load_expected()).Expect.error(error)))); + + + } - _isScopeExpanded(scope: IScope): boolean { + _isScopeExpanded(scope) { return this.state.expandedScopes.has(scope.name); } - _setScopeExpanded(scope: IScope, expanded: boolean): void { + _setScopeExpanded(scope, expanded) { if (expanded === this.state.expandedScopes.has(scope.name)) { return; } @@ -177,85 +177,84 @@ export default class ScopesComponent extends React.Component { } else { expandedScopes.delete(scope.name); } - this.setState({expandedScopes}); + this.setState({ expandedScopes }); } - render(): React.Node { - const {scopes} = this.state; + render() { + const { scopes } = this.state; if (scopes.isError) { - return Error fetching scopes: {scopes.error.toString()}; + return _react.createElement('span', null, 'Error fetching scopes: ', scopes.error.toString()); } else if (scopes.isPending) { return LOADING; } else if (scopes.value.length === 0) { - return (no variables); + return _react.createElement('span', null, '(no variables)'); } const scopeSections = scopes.value.map(scope => - this._renderScopeSection(scope), - ); + this._renderScopeSection(scope)); + return ( -
{scopeSections}
- ); - } -} + _react.createElement('div', { className: 'debugger-expression-value-list' }, scopeSections)); + + }}exports.default = ScopesComponent; + + + + + + + + +class ScopeComponent extends _react.Component {constructor(...args) {var _temp;return _temp = super(...args), this. + + -type ScopeProps = { - variables: Expected>, - canSetVariables: boolean, - getExpansionStateIdForExpression: (name: string) => Object, -}; -class ScopeComponent extends React.Component { - render() { - const {variables} = this.props; - if (variables.isError) { - return ( -
Error fetching scope variables {variables.error.toString()}
- ); - } else if (variables.isPending) { - return LOADING; - } else if (variables.value.length === 0) { - return NO_VARIABLES; - } else { - return variables.value.map(variable => this._renderVariable(variable)); - } - } - _setVariable = (expression: ?string, newValue: ?string): void => { - const {variables} = this.props; - if ( + + + + + + + + + + + _setVariable = (expression, newValue) => { + const { variables } = this.props; + if ( !Boolean(expression) || !Boolean(newValue) || variables.isError || - variables.isPending - ) { - return; - } - const variable = variables.value.find(v => v.name === expression); - if (variable == null) { - return; - } - invariant(newValue != null); - variable.setVariable(newValue).then(() => this.forceUpdate()); - }; + variables.isPending) + { + return; + } + const variable = variables.value.find(v => v.name === expression); + if (variable == null) { + return; + }if (!( + newValue != null)) {throw new Error('Invariant violation: "newValue != null"');} + variable.setVariable(newValue).then(() => this.forceUpdate()); + }, _temp;}render() {const { variables } = this.props;if (variables.isError) {return _react.createElement('div', null, 'Error fetching scope variables ', variables.error.toString());} else if (variables.isPending) {return LOADING;} else if (variables.value.length === 0) {return NO_VARIABLES;} else {return variables.value.map(variable => this._renderVariable(variable));}} - _renderVariable(expression: IVariable): ?React.Element { + _renderVariable(expression) { return ( -
-
- -
-
- ); - } -} + _react.createElement('div', { + className: 'debugger-expression-value-row debugger-scope', + key: expression.getId() }, + _react.createElement('div', { className: 'debugger-expression-value-content' }, + _react.createElement((_LazyNestedValueComponent || _load_LazyNestedValueComponent()).LazyNestedValueComponent, { + expression: expression.name, + evaluationResult: (0, (_utils || _load_utils()).expressionAsEvaluationResult)(expression), + fetchChildren: (_utils || _load_utils()).fetchChildrenForLazyComponent, + simpleValueComponent: (_SimpleValueComponent || _load_SimpleValueComponent()).default, + expansionStateId: this.props.getExpansionStateIdForExpression( + expression.name), + + setVariable: this.props.canSetVariables ? this._setVariable : null })))); + + + + + }} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/ScopesView.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/ScopesView.js index 0bd45007..1580bd91 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/ScopesView.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/ScopesView.js @@ -1,68 +1,77 @@ -/** - * 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 - * @format - */ - -import type {DebuggerModeType, IDebugService} from '../types'; - -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import * as React from 'react'; -import classnames from 'classnames'; -import ScopesComponent from './ScopesComponent'; -import {DebuggerMode} from '../constants'; - -type Props = { - service: IDebugService, -}; -type State = { - mode: DebuggerModeType, -}; - -export default class ScopesView extends React.PureComponent { - _scopesComponentWrapped: React.ComponentType; - _disposables: UniversalDisposable; - - constructor(props: Props) { +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _event; + + + + + + + + + + + + + +function _load_event() {return _event = require('nuclide-commons/event');}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));} +var _react = _interopRequireWildcard(require('react'));var _classnames; +function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));}var _ScopesComponent; +function _load_ScopesComponent() {return _ScopesComponent = _interopRequireDefault(require('./ScopesComponent'));}var _constants; +function _load_constants() {return _constants = require('../constants');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + + + + + + + + +class ScopesView extends _react.PureComponent { + + + + constructor(props) { super(props); - this._disposables = new UniversalDisposable(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this.state = { - mode: props.service.getDebuggerMode(), - }; + mode: props.service.getDebuggerMode() }; + } - componentDidMount(): void { - const {service} = this.props; + componentDidMount() { + const { service } = this.props; this._disposables.add( - observableFromSubscribeFunction( - service.onDidChangeMode.bind(service), - ).subscribe(mode => this.setState({mode})), - ); + (0, (_event || _load_event()).observableFromSubscribeFunction)( + service.onDidChangeMode.bind(service)). + subscribe(mode => this.setState({ mode }))); + } - componentWillUnmount(): void { + componentWillUnmount() { this._disposables.dispose(); } - render(): React.Node { - const {service} = this.props; - const {mode} = this.state; + render() { + const { service } = this.props; + const { mode } = this.state; const disabledClass = - mode !== DebuggerMode.RUNNING ? '' : ' debugger-container-new-disabled'; + mode !== (_constants || _load_constants()).DebuggerMode.RUNNING ? '' : ' debugger-container-new-disabled'; return ( -
-
- -
-
- ); - } -} + _react.createElement('div', { className: (0, (_classnames || _load_classnames()).default)('debugger-container-new', disabledClass) }, + _react.createElement('div', { className: 'debugger-pane-content' }, + _react.createElement((_ScopesComponent || _load_ScopesComponent()).default, { service: service })))); + + + + }}exports.default = ScopesView; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/ThreadsView.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/ThreadsView.js index 50db0287..b0ca0663 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/ThreadsView.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/ThreadsView.js @@ -1,73 +1,82 @@ -/** - * 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 - * @format - */ - -import type {DebuggerModeType, IDebugService} from '../types'; - -import classnames from 'classnames'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import * as React from 'react'; -import DebuggerThreadsComponent from './DebuggerThreadsComponent'; -import {DebuggerMode} from '../constants'; - -type Props = { - service: IDebugService, -}; - -export default class ThreadsView extends React.PureComponent< - Props, - { - mode: DebuggerModeType, - }, -> { - _disposables: UniversalDisposable; - - constructor(props: Props) { +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _classnames; + + + + + + + + + + + + + +function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));}var _event; +function _load_event() {return _event = require('nuclide-commons/event');}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));} +var _react = _interopRequireWildcard(require('react'));var _DebuggerThreadsComponent; +function _load_DebuggerThreadsComponent() {return _DebuggerThreadsComponent = _interopRequireDefault(require('./DebuggerThreadsComponent'));}var _constants; +function _load_constants() {return _constants = require('../constants');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + + + + + +class ThreadsView extends _react.PureComponent + + + + +{ + + + constructor(props) { super(props); - this._disposables = new UniversalDisposable(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); this.state = { - mode: props.service.getDebuggerMode(), - }; + mode: props.service.getDebuggerMode() }; + } - componentDidMount(): void { - const {service} = this.props; + componentDidMount() { + const { service } = this.props; this._disposables.add( - observableFromSubscribeFunction( - service.onDidChangeMode.bind(service), - ).subscribe(mode => this.setState({mode})), - ); + (0, (_event || _load_event()).observableFromSubscribeFunction)( + service.onDidChangeMode.bind(service)). + subscribe(mode => this.setState({ mode }))); + } - componentWillUnmount(): void { + componentWillUnmount() { this._dispose(); } - _dispose(): void { + _dispose() { this._disposables.dispose(); } - render(): React.Node { - const {service} = this.props; - const {mode} = this.state; + render() { + const { service } = this.props; + const { mode } = this.state; const disabledClass = - mode !== DebuggerMode.RUNNING ? '' : ' debugger-container-new-disabled'; + mode !== (_constants || _load_constants()).DebuggerMode.RUNNING ? '' : ' debugger-container-new-disabled'; return ( -
-
- -
-
- ); - } -} + _react.createElement('div', { className: (0, (_classnames || _load_classnames()).default)('debugger-container-new', disabledClass) }, + _react.createElement('div', { className: 'debugger-pane-content' }, + _react.createElement((_DebuggerThreadsComponent || _load_DebuggerThreadsComponent()).default, { service: service })))); + + + + }}exports.default = ThreadsView; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/WatchExpressionComponent.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/WatchExpressionComponent.js index 9de17530..56ff82b8 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/WatchExpressionComponent.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/WatchExpressionComponent.js @@ -1,210 +1,219 @@ -/** - * 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 - * @format - */ - -import type {IEvaluatableExpression, IStackFrame, IProcess} from '../types'; - -import {Observable} from 'rxjs'; -import * as React from 'react'; -import classnames from 'classnames'; -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import nullthrows from 'nullthrows'; -import {LazyNestedValueComponent} from 'nuclide-commons-ui/LazyNestedValueComponent'; -import SimpleValueComponent from 'nuclide-commons-ui/SimpleValueComponent'; -import {Icon} from 'nuclide-commons-ui/Icon'; -import { - expressionAsEvaluationResultStream, - fetchChildrenForLazyComponent, -} from '../utils'; - -type Props = { - watchExpressions: Array, - focusedStackFrame: ?IStackFrame, - focusedProcess: ?IProcess, - onAddWatchExpression: (expression: string) => void, - onRemoveWatchExpression: (id: string) => void, - onUpdateWatchExpression: (id: string, newExpression: string) => void, -}; - -type State = { - rowBeingEdited: ?string, -}; - -export default class WatchExpressionComponent extends React.Component< - Props, - State, -> { - coreCancelDisposable: ?IDisposable; - _newExpressionEditor: ?AtomInput; - _editExpressionEditor: ?AtomInput; - _expansionStates: Map< - string /* expression */, - /* unique reference for expression */ Object, - >; - - constructor(props: Props) { - super(props); - this._expansionStates = new Map(); - this.state = { - rowBeingEdited: null, - }; - } - - _getExpansionStateIdForExpression(expression: string): Object { - let expansionStateId = this._expansionStates.get(expression); - if (expansionStateId == null) { - expansionStateId = {}; - this._expansionStates.set(expression, expansionStateId); - } - return expansionStateId; - } - - removeExpression(id: string, event: MouseEvent): void { - event.stopPropagation(); - this.props.onRemoveWatchExpression(id); - } - - addExpression(expression: string): void { - this.props.onAddWatchExpression(expression); - } - - _onConfirmNewExpression = (): void => { - const text = nullthrows(this._newExpressionEditor).getText(); - this.addExpression(text); - nullthrows(this._newExpressionEditor).setText(''); - }; - - _onConfirmExpressionEdit(id: string): void { - const text = nullthrows(this._editExpressionEditor).getText(); - this.props.onUpdateWatchExpression(id, text); - this._resetExpressionEditState(); - } - - _setRowBeingEdited(id: string): void { - this.setState({ - rowBeingEdited: id, - }); - if (this.coreCancelDisposable) { - this.coreCancelDisposable.dispose(); - } - this.coreCancelDisposable = atom.commands.add('atom-workspace', { - 'core:cancel': () => this._resetExpressionEditState(), - }); - } - - _resetExpressionEditState = (): void => { - if (this.coreCancelDisposable) { - this.coreCancelDisposable.dispose(); - this.coreCancelDisposable = null; - } - this.setState({rowBeingEdited: null}); - }; - - _renderExpression = ( - watchExpression: IEvaluatableExpression, - ): React.Element => { - const {focusedProcess, focusedStackFrame} = this.props; - const id = watchExpression.getId(); - let evalResult; - if (id === this.state.rowBeingEdited) { - return ( - { - this._editExpressionEditor = input; - }} - size="sm" - initialValue={watchExpression.name} - /> - ); - } else if (focusedProcess == null) { - evalResult = Observable.of(null); - } else { - evalResult = expressionAsEvaluationResultStream( +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); + + + + + + + + + + + + + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); +var _react = _interopRequireWildcard(require('react'));var _classnames; +function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));}var _AtomInput; +function _load_AtomInput() {return _AtomInput = require('nuclide-commons-ui/AtomInput');}var _bindObservableAsProps; +function _load_bindObservableAsProps() {return _bindObservableAsProps = require('nuclide-commons-ui/bindObservableAsProps');}var _nullthrows; +function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));}var _LazyNestedValueComponent; +function _load_LazyNestedValueComponent() {return _LazyNestedValueComponent = require('nuclide-commons-ui/LazyNestedValueComponent');}var _SimpleValueComponent; +function _load_SimpleValueComponent() {return _SimpleValueComponent = _interopRequireDefault(require('nuclide-commons-ui/SimpleValueComponent'));}var _Icon; +function _load_Icon() {return _Icon = require('nuclide-commons-ui/Icon');}var _utils; +function _load_utils() {return _utils = require('../utils');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} + + + + + + + + + + + + + + + + + +class WatchExpressionComponent extends _react.Component + + +{ + + + + + + + + + constructor(props) { + super(props);this. + + + + + + + + + + + + + + + + + + + + + + + + + _onConfirmNewExpression = () => { + const text = (0, (_nullthrows || _load_nullthrows()).default)(this._newExpressionEditor).getText(); + this.addExpression(text); + (0, (_nullthrows || _load_nullthrows()).default)(this._newExpressionEditor).setText(''); + };this. + + + + + + + + + + + + + + + + + + + + _resetExpressionEditState = () => { + if (this.coreCancelDisposable) { + this.coreCancelDisposable.dispose(); + this.coreCancelDisposable = null; + } + this.setState({ rowBeingEdited: null }); + };this. + + _renderExpression = + watchExpression => + { + const { focusedProcess, focusedStackFrame } = this.props; + const id = watchExpression.getId(); + let evalResult; + if (id === this.state.rowBeingEdited) { + return ( + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + className: 'debugger-watch-expression-input', + autofocus: true, + startSelected: true, + key: id, + onConfirm: this._onConfirmExpressionEdit.bind(this, id), + onCancel: this._resetExpressionEditState, + onBlur: this._resetExpressionEditState, + ref: input => { + this._editExpressionEditor = input; + }, + size: 'sm', + initialValue: watchExpression.name })); + + + } else if (focusedProcess == null) { + evalResult = _rxjsBundlesRxMinJs.Observable.of(null); + } else { + evalResult = (0, (_utils || _load_utils()).expressionAsEvaluationResultStream)( watchExpression, focusedProcess, focusedStackFrame, - 'watch', - ); - } - const ValueComponent = bindObservableAsProps( - evalResult.map(evaluationResult => ({evaluationResult})), - LazyNestedValueComponent, - ); - return ( -
-
- -
-
- - -
-
- ); - }; - - render(): React.Node { + 'watch'); + + } + const ValueComponent = (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)( + evalResult.map(evaluationResult => ({ evaluationResult })), (_LazyNestedValueComponent || _load_LazyNestedValueComponent()).LazyNestedValueComponent); + + + return ( + _react.createElement('div', { + className: (0, (_classnames || _load_classnames()).default)( + 'debugger-expression-value-row', + 'debugger-watch-expression-row'), + + key: id }, + _react.createElement('div', { + className: (0, (_classnames || _load_classnames()).default)( + 'debugger-expression-value-content', + 'debugger-watch-expression-value-content'), + + onDoubleClick: this._setRowBeingEdited.bind(this, id) }, + _react.createElement(ValueComponent, { + expression: watchExpression.name, + fetchChildren: (_utils || _load_utils()).fetchChildrenForLazyComponent, + simpleValueComponent: (_SimpleValueComponent || _load_SimpleValueComponent()).default, + expansionStateId: this._getExpansionStateIdForExpression( + watchExpression.name) })), + + + + _react.createElement('div', { className: 'debugger-watch-expression-controls' }, + _react.createElement((_Icon || _load_Icon()).Icon, { + icon: 'pencil', + className: 'debugger-watch-expression-control', + onClick: this._setRowBeingEdited.bind(this, id) }), + + _react.createElement((_Icon || _load_Icon()).Icon, { + icon: 'x', + className: 'debugger-watch-expression-control', + onClick: this.removeExpression.bind(this, id) })))); + + + + + };this._expansionStates = new Map();this.state = { rowBeingEdited: null };}_getExpansionStateIdForExpression(expression) {let expansionStateId = this._expansionStates.get(expression);if (expansionStateId == null) {expansionStateId = {};this._expansionStates.set(expression, expansionStateId);}return expansionStateId;}removeExpression(id, event) {event.stopPropagation();this.props.onRemoveWatchExpression(id);}addExpression(expression) {this.props.onAddWatchExpression(expression);}_onConfirmExpressionEdit(id) {const text = (0, (_nullthrows || _load_nullthrows()).default)(this._editExpressionEditor).getText();this.props.onUpdateWatchExpression(id, text);this._resetExpressionEditState();}_setRowBeingEdited(id) {this.setState({ rowBeingEdited: id });if (this.coreCancelDisposable) {this.coreCancelDisposable.dispose();}this.coreCancelDisposable = atom.commands.add('atom-workspace', { 'core:cancel': () => this._resetExpressionEditState() });} + + render() { const expressions = this.props.watchExpressions.map(this._renderExpression); - const addNewExpressionInput = ( - { - this._newExpressionEditor = input; - }} - size="sm" - placeholderText="Add new watch expression" - /> - ); + const addNewExpressionInput = + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + className: (0, (_classnames || _load_classnames()).default)( + 'debugger-watch-expression-input', + 'debugger-watch-expression-add-new-input'), + + onConfirm: this._onConfirmNewExpression, + ref: input => { + this._newExpressionEditor = input; + }, + size: 'sm', + placeholderText: 'Add new watch expression' }); + + return ( -
- {expressions} - {addNewExpressionInput} -
- ); - } -} + _react.createElement('div', { className: 'debugger-expression-value-list' }, + expressions, + addNewExpressionInput)); + + + }}exports.default = WatchExpressionComponent; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/WatchView.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/WatchView.js index c0c90fc2..d2e1108c 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/WatchView.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/ui/WatchView.js @@ -1,86 +1,85 @@ -/** - * 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 - * @format - */ - -import type {IDebugService} from '../types'; - -import classnames from 'classnames'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import * as React from 'react'; -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import {Observable} from 'rxjs'; -import WatchExpressionComponent from './WatchExpressionComponent'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; - -type Props = { - service: IDebugService, -}; - -export default class WatchView extends React.PureComponent { - _watchExpressionComponentWrapped: React.ComponentType; - _disposables: UniversalDisposable; - - constructor(props: Props) { +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _classnames; + + + + + + + + + + + + + +function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));} +var _react = _interopRequireWildcard(require('react'));var _bindObservableAsProps; +function _load_bindObservableAsProps() {return _bindObservableAsProps = require('nuclide-commons-ui/bindObservableAsProps');} +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _WatchExpressionComponent; +function _load_WatchExpressionComponent() {return _WatchExpressionComponent = _interopRequireDefault(require('./WatchExpressionComponent'));}var _event; +function _load_event() {return _event = require('nuclide-commons/event');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */class WatchView extends _react.PureComponent {constructor(props) { super(props); - const {service} = props; - const {viewModel} = service; + const { service } = props; + const { viewModel } = service; const model = service.getModel(); - const watchExpressionChanges = observableFromSubscribeFunction( - model.onDidChangeWatchExpressions.bind(model), - ); - const focusedProcessChanges = observableFromSubscribeFunction( - viewModel.onDidFocusProcess.bind(viewModel), - ); - const focusedStackFrameChanges = observableFromSubscribeFunction( - viewModel.onDidFocusStackFrame.bind(viewModel), - ); - const expressionContextChanges = observableFromSubscribeFunction( - viewModel.onDidChangeExpressionContext.bind(viewModel), - ); - this._watchExpressionComponentWrapped = bindObservableAsProps( - Observable.merge( - watchExpressionChanges, - focusedProcessChanges, - focusedStackFrameChanges, - expressionContextChanges, - ) - .startWith(null) - .map(() => ({ - focusedProcess: viewModel.focusedProcess, - focusedStackFrame: viewModel.focusedStackFrame, - watchExpressions: model.getWatchExpressions(), - })), - WatchExpressionComponent, - ); + const watchExpressionChanges = (0, (_event || _load_event()).observableFromSubscribeFunction)( + model.onDidChangeWatchExpressions.bind(model)); + + const focusedProcessChanges = (0, (_event || _load_event()).observableFromSubscribeFunction)( + viewModel.onDidFocusProcess.bind(viewModel)); + + const focusedStackFrameChanges = (0, (_event || _load_event()).observableFromSubscribeFunction)( + viewModel.onDidFocusStackFrame.bind(viewModel)); + + const expressionContextChanges = (0, (_event || _load_event()).observableFromSubscribeFunction)( + viewModel.onDidChangeExpressionContext.bind(viewModel)); + + this._watchExpressionComponentWrapped = (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)( + _rxjsBundlesRxMinJs.Observable.merge( + watchExpressionChanges, + focusedProcessChanges, + focusedStackFrameChanges, + expressionContextChanges). + + startWith(null). + map(() => ({ + focusedProcess: viewModel.focusedProcess, + focusedStackFrame: viewModel.focusedStackFrame, + watchExpressions: model.getWatchExpressions() })), (_WatchExpressionComponent || _load_WatchExpressionComponent()).default); + + + } - render(): React.Node { - const {service} = this.props; - const WatchExpressionComponentWrapped = this - ._watchExpressionComponentWrapped; + render() { + const { service } = this.props; + const WatchExpressionComponentWrapped = this. + _watchExpressionComponentWrapped; return ( -
-
- -
-
- ); - } -} + _react.createElement('div', { className: (0, (_classnames || _load_classnames()).default)('debugger-container-new') }, + _react.createElement('div', { className: 'debugger-pane-content' }, + _react.createElement(WatchExpressionComponentWrapped, { + onAddWatchExpression: service.addWatchExpression.bind(service), + onRemoveWatchExpression: service.removeWatchExpressions.bind( + service), + + onUpdateWatchExpression: service.renameWatchExpression.bind( + service) })))); + + + + + + }}exports.default = WatchView; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/utils.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/utils.js index ad588502..7aff7be6 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/utils.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/utils.js @@ -1,173 +1,182 @@ -/** - * 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 - * @format - */ - -import type { - IExpression, - IEvaluatableExpression, - IProcess, - IStackFrame, - ContextType, -} from './types'; -import type {EvaluationResult} from 'nuclide-commons-ui/TextRenderer'; -import type {ExpansionResult} from 'nuclide-commons-ui/LazyNestedValueComponent'; - -import nullthrows from 'nullthrows'; -import {Observable} from 'rxjs'; -import logger from './logger'; - -function getGutterLineNumber(target: HTMLElement): ?number { - const eventLine = parseInt(target.dataset.line, 10); - if (eventLine != null && eventLine >= 0 && !isNaN(Number(eventLine))) { - return eventLine; - } -} - -const SCREEN_ROW_ATTRIBUTE_NAME = 'data-screen-row'; - -function getEditorLineNumber( - editor: atom$TextEditor, - target: HTMLElement, -): ?number { - let node = target; - while (node != null) { - if (node.hasAttribute(SCREEN_ROW_ATTRIBUTE_NAME)) { - const screenRow = Number(node.getAttribute(SCREEN_ROW_ATTRIBUTE_NAME)); - try { - return editor.bufferPositionForScreenPosition([screenRow, 0]).row; - } catch (error) { - return null; - } - } - node = node.parentElement; - } -} - -export async function openSourceLocation( - path: string, - line: number, -): Promise { - // eslint-disable-next-line rulesdir/atom-apis - const editor = await atom.workspace.open(path, { - searchAllPanes: true, - pending: true, - }); - editor.scrollToBufferPosition([line, 0]); - editor.setCursorBufferPosition([line, 0]); - return editor; -} - -function firstNonNull(...args) { - return nullthrows(args.find(arg => arg != null)); -} - -export function getLineForEvent(editor: atom$TextEditor, event: any): number { - const cursorLine = editor.getLastCursor().getBufferRow(); - const target = event ? (event.target: HTMLElement) : null; - if (target == null) { - return cursorLine; - } - // toggleLine is the line the user clicked in the gutter next to, as opposed +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.openSourceLocation = undefined;var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));let openSourceLocation = exports.openSourceLocation = (() => {var _ref = (0, _asyncToGenerator.default)( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + function* ( + path, + line) + { + // eslint-disable-next-line rulesdir/atom-apis + const editor = yield atom.workspace.open(path, { + searchAllPanes: true, + pending: true }); + + editor.scrollToBufferPosition([line, 0]); + editor.setCursorBufferPosition([line, 0]); + return editor; + });return function openSourceLocation(_x, _x2) {return _ref.apply(this, arguments);};})();exports. + + + + + +getLineForEvent = getLineForEvent;exports. + + + + + + + + + + + + + + + + +isLocalScopeName = isLocalScopeName;exports. + + + +expressionAsEvaluationResult = expressionAsEvaluationResult;exports. + + + + + + + + + + + + + + + + + + + + + +expressionAsEvaluationResultStream = expressionAsEvaluationResultStream;exports. + + + + + + + + + + + + + + + + + + + + +fetchChildrenForLazyComponent = fetchChildrenForLazyComponent;exports. + + + + + + + + + + + + + + +onUnexpectedError = onUnexpectedError;exports. + + + + + + + + + + +capitalize = capitalize;exports. + + + +notifyOpenDebugSession = notifyOpenDebugSession;var _nullthrows;function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));}var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _logger;function _load_logger() {return _logger = _interopRequireDefault(require('./logger'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */function getGutterLineNumber(target) {const eventLine = parseInt(target.dataset.line, 10);if (eventLine != null && eventLine >= 0 && !isNaN(Number(eventLine))) {return eventLine;}}const SCREEN_ROW_ATTRIBUTE_NAME = 'data-screen-row';function getEditorLineNumber(editor, target) {let node = target;while (node != null) {if (node.hasAttribute(SCREEN_ROW_ATTRIBUTE_NAME)) {const screenRow = Number(node.getAttribute(SCREEN_ROW_ATTRIBUTE_NAME));try {return editor.bufferPositionForScreenPosition([screenRow, 0]).row;} catch (error) {return null;}}node = node.parentElement;}}function firstNonNull(...args) {return (0, (_nullthrows || _load_nullthrows()).default)(args.find(arg => arg != null));}function getLineForEvent(editor, event) {const cursorLine = editor.getLastCursor().getBufferRow();const target = event ? event.target : null;if (target == null) {return cursorLine;} // toggleLine is the line the user clicked in the gutter next to, as opposed // to the line the editor's cursor happens to be in. If this command was invoked // from the menu, then the cursor position is the target line. - return firstNonNull( - getGutterLineNumber(target), - getEditorLineNumber(editor, target), - // fall back to the line the cursor is on. - cursorLine, - ); -} - -export function isLocalScopeName(scopeName: string): boolean { - return ['Local', 'Locals'].indexOf(scopeName) !== -1; -} - -export function expressionAsEvaluationResult( - expression: IExpression, -): EvaluationResult { - const value = expression.getValue(); - if (!expression.available) { - return {type: 'error', value}; - } else if (!expression.hasChildren()) { - return { - type: typeForSimpleValue(value), - value, - }; - } else { - return { - type: 'object', - description: value, - // Used a means to get children when requested later. + return firstNonNull(getGutterLineNumber(target), getEditorLineNumber(editor, target), // fall back to the line the cursor is on. + cursorLine);}function isLocalScopeName(scopeName) {return ['Local', 'Locals'].indexOf(scopeName) !== -1;}function expressionAsEvaluationResult(expression) {const value = expression.getValue();if (!expression.available) {return { type: 'error', value };} else if (!expression.hasChildren()) {return { type: typeForSimpleValue(value), value };} else {return { type: 'object', description: value, // Used a means to get children when requested later. // $FlowFixMe: that isn't an object ID, - objectId: expression, - }; - } -} - -export function expressionAsEvaluationResultStream( - expression: IEvaluatableExpression, - focusedProcess: IProcess, - focusedStackFrame: ?IStackFrame, - context: ContextType, -): Observable { - return Observable.fromPromise( - expression.evaluate(focusedProcess, focusedStackFrame, context), - ) - .map(() => expressionAsEvaluationResult(expression)) - .startWith(null); -} - -function typeForSimpleValue(value: string): string { - if (value === 'undefined' || value === 'null') { - return value; - } else { - return 'default'; - } -} - -export function fetchChildrenForLazyComponent( - expression: IExpression, -): Observable { - return Observable.fromPromise( - expression.getChildren().then( - children => - children.map(child => ({ - name: child.name, - value: expressionAsEvaluationResult(child), - })), - error => null, - ), - ); -} - -export function onUnexpectedError(error: any) { - const errorMessage = error.stack || error.message || String(error); - logger.error('Unexpected error', error); - atom.notifications.addError( - 'Atom debugger ran into an unexpected error - please file a bug!', - { - detail: errorMessage, - }, - ); -} - -export function capitalize(str: string): string { - return str[0].toUpperCase() + str.slice(1); -} - -export function notifyOpenDebugSession(): void { - atom.notifications.addInfo( - "Received a debug request, but there's an open debug session already!", - { - detail: 'Please terminate your existing debug session', - }, - ); -} + objectId: expression };}}function expressionAsEvaluationResultStream(expression, focusedProcess, focusedStackFrame, context) {return _rxjsBundlesRxMinJs.Observable.fromPromise(expression.evaluate(focusedProcess, focusedStackFrame, context)).map(() => expressionAsEvaluationResult(expression)).startWith(null);}function typeForSimpleValue(value) {if (value === 'undefined' || value === 'null') {return value;} else {return 'default';}}function fetchChildrenForLazyComponent(expression) {return _rxjsBundlesRxMinJs.Observable.fromPromise(expression.getChildren().then(children => children.map(child => ({ name: child.name, value: expressionAsEvaluationResult(child) })), error => null));}function onUnexpectedError(error) {const errorMessage = error.stack || error.message || String(error);(_logger || _load_logger()).default.error('Unexpected error', error);atom.notifications.addError('Atom debugger ran into an unexpected error - please file a bug!', { detail: errorMessage });}function capitalize(str) {return str[0].toUpperCase() + str.slice(1);}function notifyOpenDebugSession() {atom.notifications.addInfo("Received a debug request, but there's an open debug session already!", { detail: 'Please terminate your existing debug session' });} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/vsp/DebugService.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/vsp/DebugService.js index c919e355..ec7ae246 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/vsp/DebugService.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/vsp/DebugService.js @@ -1,1642 +1,1642 @@ -/** - * 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 - * @format - */ - -/** -The following debug service implementation was ported from VSCode's debugger implementation -in https://github.com/Microsoft/vscode/tree/master/src/vs/workbench/parts/debug - -MIT License - -Copyright (c) 2015 - present Microsoft Corporation - -All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -import type {ConsoleMessage} from 'atom-ide-ui'; -import type {TerminalInfo} from '../../../atom-ide-terminal/lib/types'; -import type { - DebuggerModeType, - IDebugService, - IModel, - IViewModel, - IProcess, - IThread, - IEnableable, - IEvaluatableExpression, - IRawBreakpoint, - IStackFrame, - SerializedState, -} from '../types'; -import type { - IProcessConfig, - MessageProcessor, - VSAdapterExecutableInfo, -} from 'nuclide-debugger-common'; -import type {EvaluationResult} from 'nuclide-commons-ui/TextRenderer'; -import type {TimingTracker} from 'nuclide-commons/analytics'; -import * as DebugProtocol from 'vscode-debugprotocol'; -import * as React from 'react'; - -import invariant from 'assert'; -import {Icon} from 'nuclide-commons-ui/Icon'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {splitStream} from 'nuclide-commons/observable'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import {sleep, serializeAsyncCall} from 'nuclide-commons/promise'; -import { - VsDebugSession, - localToRemoteProcessor, - remoteToLocalProcessor, - getVSCodeDebuggerAdapterServiceByNuclideUri, -} from 'nuclide-debugger-common'; -import {Observable, Subject, TimeoutError} from 'rxjs'; -import {TextEditorBanner} from 'nuclide-commons-ui/TextEditorBanner'; -import ReadOnlyNotice from 'nuclide-commons-ui/ReadOnlyNotice'; -import {track, startTracking} from 'nuclide-commons/analytics'; -import nullthrows from 'nullthrows'; -import { - getConsoleRegisterExecutor, - getConsoleService, - getNotificationService, - getDatatipService, - getTerminalService, - resolveDebugConfiguration, -} from '../AtomServiceContainer'; -import { - expressionAsEvaluationResultStream, - fetchChildrenForLazyComponent, - capitalize, -} from '../utils'; -import { - Model, - ExceptionBreakpoint, - FunctionBreakpoint, - Breakpoint, - Expression, - Process, -} from './DebuggerModel'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Emitter, TextBuffer} from 'atom'; -import {distinct, mapFromObject} from 'nuclide-commons/collection'; -import {onUnexpectedError, notifyOpenDebugSession} from '../utils'; -import uuid from 'uuid'; -import { - BreakpointEventReasons, - DebuggerMode, - AnalyticsEvents, - DEBUG_SOURCES_URI, -} from '../constants'; -import logger from '../logger'; -import stripAnsi from 'strip-ansi'; -import url from 'url'; -import idx from 'idx'; - -const CONSOLE_VIEW_URI = 'atom://nuclide/console'; - -const CUSTOM_DEBUG_EVENT = 'CUSTOM_DEBUG_EVENT'; -const CHANGE_DEBUG_MODE = 'CHANGE_DEBUG_MODE'; - -const CHANGE_FOCUSED_PROCESS = 'CHANGE_FOCUSED_PROCESS'; -const CHANGE_FOCUSED_STACKFRAME = 'CHANGE_FOCUSED_STACKFRAME'; -const CHANGE_EXPRESSION_CONTEXT = 'CHANGE_EXPRESSION_CONTEXT'; - -// Berakpoint events may arrive sooner than breakpoint responses. -const MAX_BREAKPOINT_EVENT_DELAY_MS = 5 * 1000; - -class ViewModel implements IViewModel { - _focusedProcess: ?IProcess; - _focusedThread: ?IThread; - _focusedStackFrame: ?IStackFrame; - _emitter: Emitter; - - constructor() { - this._focusedProcess = null; - this._focusedThread = null; - this._focusedStackFrame = null; - this._emitter = new Emitter(); +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _vscodeDebugprotocol; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +function _load_vscodeDebugprotocol() {return _vscodeDebugprotocol = _interopRequireWildcard(require('vscode-debugprotocol'));} +var _react = _interopRequireWildcard(require('react'));var _Icon; + + +function _load_Icon() {return _Icon = require('nuclide-commons-ui/Icon');}var _nuclideUri; +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));}var _observable; +function _load_observable() {return _observable = require('nuclide-commons/observable');}var _event; +function _load_event() {return _event = require('nuclide-commons/event');}var _promise; +function _load_promise() {return _promise = require('nuclide-commons/promise');}var _nuclideDebuggerCommon; +function _load_nuclideDebuggerCommon() {return _nuclideDebuggerCommon = require('nuclide-debugger-common');} + + + + + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _TextEditorBanner; +function _load_TextEditorBanner() {return _TextEditorBanner = require('nuclide-commons-ui/TextEditorBanner');}var _ReadOnlyNotice; +function _load_ReadOnlyNotice() {return _ReadOnlyNotice = _interopRequireDefault(require('nuclide-commons-ui/ReadOnlyNotice'));}var _analytics; +function _load_analytics() {return _analytics = require('nuclide-commons/analytics');}var _nullthrows; +function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));}var _AtomServiceContainer; +function _load_AtomServiceContainer() {return _AtomServiceContainer = require('../AtomServiceContainer');}var _utils; + + + + + + + +function _load_utils() {return _utils = require('../utils');}var _DebuggerModel; + + + + +function _load_DebuggerModel() {return _DebuggerModel = require('./DebuggerModel');}var _UniversalDisposable; + + + + + + + +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));} +var _atom = require('atom');var _collection; +function _load_collection() {return _collection = require('nuclide-commons/collection');}var _uuid; + +function _load_uuid() {return _uuid = _interopRequireDefault(require('uuid'));}var _constants; +function _load_constants() {return _constants = require('../constants');}var _logger; + + + + + +function _load_logger() {return _logger = _interopRequireDefault(require('../logger'));}var _stripAnsi; +function _load_stripAnsi() {return _stripAnsi = _interopRequireDefault(require('strip-ansi'));} +var _url = _interopRequireDefault(require('url'));var _idx; +function _load_idx() {return _idx = _interopRequireDefault(require('idx'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */ /** + The following debug service implementation was ported from VSCode's debugger implementation + in https://github.com/Microsoft/vscode/tree/master/src/vs/workbench/parts/debug + + MIT License + + Copyright (c) 2015 - present Microsoft Corporation + + All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */const CONSOLE_VIEW_URI = 'atom://nuclide/console';const CUSTOM_DEBUG_EVENT = 'CUSTOM_DEBUG_EVENT';const CHANGE_DEBUG_MODE = 'CHANGE_DEBUG_MODE';const CHANGE_FOCUSED_PROCESS = 'CHANGE_FOCUSED_PROCESS';const CHANGE_FOCUSED_STACKFRAME = 'CHANGE_FOCUSED_STACKFRAME';const CHANGE_EXPRESSION_CONTEXT = 'CHANGE_EXPRESSION_CONTEXT'; // Berakpoint events may arrive sooner than breakpoint responses. +const MAX_BREAKPOINT_EVENT_DELAY_MS = 5 * 1000;class ViewModel {constructor() {this._focusedProcess = null;this._focusedThread = null;this._focusedStackFrame = null;this._emitter = new _atom.Emitter();}get focusedProcess() {return this._focusedProcess;}get focusedThread() {return this._focusedStackFrame != null ? this._focusedStackFrame.thread : this._focusedThread;}get focusedStackFrame() {return this._focusedStackFrame; + } + + onDidFocusProcess(callback) { + return this._emitter.on(CHANGE_FOCUSED_PROCESS, callback); } - get focusedProcess(): ?IProcess { - return this._focusedProcess; - } + onDidFocusStackFrame( + callback) + { + return this._emitter.on(CHANGE_FOCUSED_STACKFRAME, callback); + } + + onDidChangeExpressionContext( + callback) + { + return this._emitter.on(CHANGE_EXPRESSION_CONTEXT, callback); + } + + isMultiProcessView() { + return false; + } + + setFocus( + stackFrame, + thread, + process, + explicit) + { + const shouldEmit = + this._focusedProcess !== process || + this._focusedThread !== thread || + this._focusedStackFrame !== stackFrame || + explicit; + if (this._focusedProcess !== process) { + this._focusedProcess = process; + this._emitter.emit(CHANGE_FOCUSED_PROCESS, process); + } + this._focusedThread = thread; + this._focusedStackFrame = stackFrame; + + if (shouldEmit) { + this._emitter.emit(CHANGE_FOCUSED_STACKFRAME, { stackFrame, explicit }); + } else { + // The focused stack frame didn't change, but something about the + // context did, so interested listeners should re-evaluate expressions. + this._emitter.emit(CHANGE_EXPRESSION_CONTEXT, { stackFrame, explicit }); + } + }} + + +function getDebuggerName(adapterType) { + return `${(0, (_utils || _load_utils()).capitalize)(adapterType)} Debugger`; +} + +class DebugService { + + + + + + + + + + + constructor(state) {var _this = this;this. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - get focusedThread(): ?IThread { - return this._focusedStackFrame != null - ? this._focusedStackFrame.thread - : this._focusedThread; - } - get focusedStackFrame(): ?IStackFrame { - return this._focusedStackFrame; - } - onDidFocusProcess(callback: (process: ?IProcess) => mixed): IDisposable { - return this._emitter.on(CHANGE_FOCUSED_PROCESS, callback); - } - onDidFocusStackFrame( - callback: (data: {stackFrame: ?IStackFrame, explicit: boolean}) => mixed, - ): IDisposable { - return this._emitter.on(CHANGE_FOCUSED_STACKFRAME, callback); - } - onDidChangeExpressionContext( - callback: (data: {stackFrame: ?IStackFrame, explicit: boolean}) => mixed, - ): IDisposable { - return this._emitter.on(CHANGE_EXPRESSION_CONTEXT, callback); - } - isMultiProcessView(): boolean { - return false; - } - setFocus( - stackFrame: ?IStackFrame, - thread: ?IThread, - process: ?IProcess, - explicit: boolean, - ): void { - const shouldEmit = - this._focusedProcess !== process || - this._focusedThread !== thread || - this._focusedStackFrame !== stackFrame || - explicit; - if (this._focusedProcess !== process) { - this._focusedProcess = process; - this._emitter.emit(CHANGE_FOCUSED_PROCESS, process); - } - this._focusedThread = thread; - this._focusedStackFrame = stackFrame; - if (shouldEmit) { - this._emitter.emit(CHANGE_FOCUSED_STACKFRAME, {stackFrame, explicit}); - } else { - // The focused stack frame didn't change, but something about the - // context did, so interested listeners should re-evaluate expressions. - this._emitter.emit(CHANGE_EXPRESSION_CONTEXT, {stackFrame, explicit}); - } - } -} -function getDebuggerName(adapterType: string): string { - return `${capitalize(adapterType)} Debugger`; -} -export default class DebugService implements IDebugService { - _model: Model; - _disposables: UniversalDisposable; - _sessionEndDisposables: UniversalDisposable; - _consoleDisposables: IDisposable; - _debuggerMode: DebuggerModeType; - _emitter: Emitter; - _viewModel: ViewModel; - _timer: ?TimingTracker; - _breakpointsToSendOnSave: Set; - - constructor(state: ?SerializedState) { - this._disposables = new UniversalDisposable(); - this._sessionEndDisposables = new UniversalDisposable(); - this._consoleDisposables = new UniversalDisposable(); - this._emitter = new Emitter(); - this._debuggerMode = DebuggerMode.STOPPED; - this._viewModel = new ViewModel(); - this._breakpointsToSendOnSave = new Set(); - - this._model = new Model( - this._loadBreakpoints(state), - true, - this._loadFunctionBreakpoints(state), - this._loadExceptionBreakpoints(state), - this._loadWatchExpressions(state), - ); - this._disposables.add(this._model); - this._registerListeners(); - } - get viewModel(): IViewModel { - return this._viewModel; - } - getDebuggerMode(): DebuggerModeType { - return this._debuggerMode; - } - _registerListeners(): void { - this._disposables.add( - atom.workspace.addOpener(uri => { - if (uri.startsWith(DEBUG_SOURCES_URI)) { - if (this._debuggerMode !== DebuggerMode.STOPPED) { - return this._openSourceView(uri); - } else { - throw new Error( - 'Cannot open debug source views - no active debug session', - ); - } - } - }), - ); - } - async _openSourceView(uri: string): Promise { - const query = (url.parse(uri).path || '').split('/'); - const [, sessionId, sourceReferenceRaw] = query; - const sourceReference = parseInt(sourceReferenceRaw, 10); - const process = - this._model.getProcesses().find(p => p.getId() === sessionId) || - this._viewModel.focusedProcess; - if (process == null) { - throw new Error(`No debug session for source: ${sourceReference}`); - } - const source = process.getSource({ - path: uri, - sourceReference, - }); - let content = ''; - try { - const response = await process.session.source({ - sourceReference, - source: source.raw, - }); - content = response.body.content; - } catch (error) { - this._sourceIsNotAvailable(uri); - throw new Error('Debug source is not available'); - } - const editor = atom.workspace.buildTextEditor({ - buffer: new DebugSourceTextBufffer(content, uri), - autoHeight: false, - readOnly: true, - }); - - // $FlowFixMe Debugger source views shouldn't persist between reload. - editor.serialize = () => null; - editor.setGrammar(atom.grammars.selectGrammar(source.name || '', content)); - const textEditorBanner = new TextEditorBanner(editor); - textEditorBanner.render( - , - ); - - const disposable = new UniversalDisposable( - textEditorBanner, - editor.onDidDestroy(() => disposable.dispose()), - () => editor.destroy(), - ); - - this._sessionEndDisposables.add(disposable); - - return editor; - } - /** - * Stops the process. If the process does not exist then stops all processes. - */ - async stopProcess(): Promise { - if ( - this._debuggerMode === DebuggerMode.STOPPING || - this._debuggerMode === DebuggerMode.STOPPED - ) { - return; - } - this._onSessionEnd(); - } - _tryToAutoFocusStackFrame(thread: IThread): void { - const callStack = thread.getCallStack(); - if ( - callStack.length === 0 || - (this._viewModel.focusedStackFrame && - this._viewModel.focusedStackFrame.thread.getId() === thread.getId() && - callStack.includes(this._viewModel.focusedStackFrame)) - ) { - return; - } - // Focus first stack frame from top that has source location if no other stack frame is focused - const stackFrameToFocus = callStack.find( - sf => sf.source != null && sf.source.available, - ); - if (stackFrameToFocus == null) { - return; - } - this.focusStackFrame(stackFrameToFocus, null, null); - } - _registerMarkers(): IDisposable { - let selectedFrameMarker: ?atom$Marker = null; - let threadChangeDatatip: ?IDisposable; - let lastFocusedThreadId: ?number; - const cleaupMarkers = () => { - if (selectedFrameMarker != null) { - selectedFrameMarker.destroy(); - selectedFrameMarker = null; - } - if (threadChangeDatatip != null) { - threadChangeDatatip.dispose(); - threadChangeDatatip = null; - } - }; - return new UniversalDisposable( - observableFromSubscribeFunction( - this._viewModel.onDidFocusStackFrame.bind(this._viewModel), - ) - .concatMap(event => { - cleaupMarkers(); - - const {stackFrame, explicit} = event; - - if (stackFrame == null || !stackFrame.source.available) { - if (explicit) { - atom.notifications.addWarning( - 'No source available for the selected stack frame', - ); - } - return Observable.empty(); - } - return Observable.fromPromise(stackFrame.openInEditor()).switchMap( - editor => { - if (editor == null) { - atom.notifications.addError( - 'Failed to open source file for stack frame!', - ); - return Observable.empty(); - } - return Observable.of({editor, explicit, stackFrame}); - }, - ); - }) - .subscribe(({editor, explicit, stackFrame}) => { - const line = stackFrame.range.start.row; - selectedFrameMarker = editor.markBufferRange( - [[line, 0], [line, Infinity]], - { - invalidate: 'never', - }, - ); - editor.decorateMarker(selectedFrameMarker, { - type: 'line', - class: 'debugger-current-line-highlight', - }); - - const datatipService = getDatatipService(); - if (datatipService == null) { - return; - } - - if ( - lastFocusedThreadId != null && - !explicit && - stackFrame.thread.threadId !== lastFocusedThreadId - ) { - const message = `Active thread changed from ${lastFocusedThreadId} to ${ - stackFrame.thread.threadId - }`; - threadChangeDatatip = datatipService.createPinnedDataTip( - { - component: () => ( -
- - {message} -
- ), - range: stackFrame.range, - pinnable: true, - }, - editor, - ); - } - lastFocusedThreadId = stackFrame.thread.threadId; - }), - - cleaupMarkers, - ); - } - _registerSessionListeners(process: Process, session: VsDebugSession): void { - this._sessionEndDisposables = new UniversalDisposable(session); - this._sessionEndDisposables.add(this._registerMarkers()); - const sessionId = session.getId(); - const threadFetcher = serializeAsyncCall(async () => { - const response = await session.threads(); - if (response && response.body && response.body.threads) { - response.body.threads.forEach(thread => { - this._model.rawUpdate({ - sessionId, - thread, - }); - }); - } - }); - - const openFilesSaved = observableFromSubscribeFunction( - atom.workspace.observeTextEditors.bind(atom.workspace), - ).flatMap(editor => { - return observableFromSubscribeFunction(editor.onDidSave.bind(editor)) - .map(() => editor.getPath()) - .takeUntil( - observableFromSubscribeFunction(editor.onDidDestroy.bind(editor)), - ); - }); - - this._sessionEndDisposables.add( - openFilesSaved.subscribe(async filePath => { - if (filePath == null || !this._breakpointsToSendOnSave.has(filePath)) { - return; - } - this._breakpointsToSendOnSave.delete(filePath); - await this._sendBreakpoints(filePath, true); - }), - ); - - this._sessionEndDisposables.add( - session.observeInitializeEvents().subscribe(async event => { - const sendConfigurationDone = async () => { - if ( - session && - session.getCapabilities().supportsConfigurationDoneRequest - ) { - return session.configurationDone().catch(e => { - // Disconnect the debug session on configuration done error #10596 - this._onSessionEnd(); - session.disconnect().catch(onUnexpectedError); - atom.notifications.addError('Failed to configure debugger', { - detail: e.message, - }); - }); - } - }; - - try { - await this._sendAllBreakpoints().then( - sendConfigurationDone, - sendConfigurationDone, - ); - await threadFetcher(); - } catch (error) { - onUnexpectedError(error); - } - }), - ); - - const toFocusThreads = new Subject(); - - const observeContinuedTo = (threadId: ?number) => { - return session - .observeContinuedEvents() - .filter( - continued => - continued.body.allThreadsContinued || - (threadId != null && threadId === continued.body.threadId), - ) - .take(1); - }; - this._sessionEndDisposables.add( - session.observeStopEvents().subscribe(() => { - this._updateModeAndEmit(DebuggerMode.PAUSED); - }), - session - .observeStopEvents() - .flatMap(event => - Observable.fromPromise(threadFetcher()) - .ignoreElements() - .concat(Observable.of(event)) - .catch(error => { - onUnexpectedError(error); - return Observable.empty(); - }) - // Proceeed processing the stopped event only if there wasn't - // a continued event while we're fetching the threads - .takeUntil(observeContinuedTo(event.body.threadId)), - ) - .subscribe((event: DebugProtocol.StoppedEvent) => { - const {threadId} = event.body; - // Updating stopped state needs to happen after fetching the threads - this._model.rawUpdate({ - sessionId, - stoppedDetails: (event.body: any), - threadId, - }); - - if (threadId == null) { - return; - } - const thread = process.getThread(threadId); - if (thread != null) { - toFocusThreads.next(thread); - } - }), - - toFocusThreads - .concatMap(thread => { - const {focusedThread} = this._viewModel; - const preserveFocusHint = - idx(thread, _ => _.stoppedDetails.preserveFocusHint) || false; - - if ( - focusedThread != null && - focusedThread.stopped && - focusedThread.getId() !== thread.getId() && - preserveFocusHint - ) { - // The debugger is already stopped elsewhere. - return Observable.empty(); - } - - // UX: That'll fetch the top stack frame first (to allow the UI to focus on it), - // then the rest of the call stack. - return ( - Observable.fromPromise(this._model.fetchCallStack(thread)) - .ignoreElements() - .concat(Observable.of(thread)) - // Avoid focusing a continued thread. - .takeUntil(observeContinuedTo(thread.threadId)) - // Verify the thread is still stopped. - .filter(() => thread.stopped) - .catch(error => { - onUnexpectedError(error); - return Observable.empty(); - }) - ); - }) - .subscribe(thread => { - this._tryToAutoFocusStackFrame(thread); - this._scheduleNativeNotification(); - }), - ); - - this._sessionEndDisposables.add( - session.observeThreadEvents().subscribe(async event => { - if (event.body.reason === 'started') { - await threadFetcher(); - } else if (event.body.reason === 'exited') { - this._model.clearThreads(session.getId(), true, event.body.threadId); - } - }), - ); - - this._sessionEndDisposables.add( - session.observeTerminateDebugeeEvents().subscribe(event => { - if (event.body && event.body.restart) { - this.restartProcess().catch(err => { - atom.notifications.addError('Failed to restart debugger', { - detail: err.stack || String(err), - }); - }); - } else { - this._onSessionEnd(); - session.disconnect().catch(onUnexpectedError); - } - }), - ); - - this._sessionEndDisposables.add( - session.observeContinuedEvents().subscribe(event => { - const threadId = - event.body.allThreadsContinued !== false - ? undefined - : event.body.threadId; - this._model.clearThreads(session.getId(), false, threadId); - this.focusStackFrame(null, this._viewModel.focusedThread, null); - this._updateModeAndEmit(this._computeDebugMode()); - }), - ); - - const createConsole = getConsoleService(); - if (createConsole != null) { - const name = getDebuggerName(process.configuration.adapterType); - const consoleApi = createConsole({ - id: name, - name, - }); - this._sessionEndDisposables.add(consoleApi); - const outputEvents = session - .observeOutputEvents() - .filter( - event => event.body != null && typeof event.body.output === 'string', - ) - .share(); - const KNOWN_CATEGORIES = new Set([ - 'stderr', - 'console', - 'telemetry', - 'success', - ]); - const logStream = splitStream( - outputEvents - .filter(e => !KNOWN_CATEGORIES.has(e.body.category)) - .map(e => stripAnsi(e.body.output)), - ); - const [errorStream, warningsStream, successStream] = [ - 'stderr', - 'console', - 'success', - ].map(category => - splitStream( - outputEvents - .filter(e => category === e.body.category) - .map(e => stripAnsi(e.body.output)), - ), - ); - const notificationStream = outputEvents - .filter(e => e.body.category === 'nuclide_notification') - .map(e => ({ - type: nullthrows(e.body.data).type, - message: e.body.output, - })); - this._sessionEndDisposables.add( - errorStream.subscribe(line => { - consoleApi.append({text: line, level: 'error'}); - }), - warningsStream.subscribe(line => { - consoleApi.append({text: line, level: 'warning'}); - }), - successStream.subscribe(line => { - consoleApi.append({text: line, level: 'success'}); - }), - logStream.subscribe(line => { - consoleApi.append({text: line, level: 'log'}); - }), - notificationStream.subscribe(({type, message}) => { - atom.notifications.add(type, message); - }), - // TODO handle non string output (e.g. files & objects) - ); - } - this._sessionEndDisposables.add( - session - .observeBreakpointEvents() - .flatMap(event => { - const {breakpoint, reason} = event.body; - if ( - reason !== BreakpointEventReasons.CHANGED && - reason !== BreakpointEventReasons.REMOVED - ) { - return Observable.of({ - reason, - breakpoint, - sourceBreakpoint: null, - functionBreakpoint: null, - }); - } - - // Breakpoint events may arrive sooner than their responses. - // Hence, we'll keep them cached and try re-processing on every change to the model's breakpoints - // for a set maximum time, then discard. - return observableFromSubscribeFunction( - this._model.onDidChangeBreakpoints.bind(this._model), - ) - .startWith(null) - .switchMap(() => { - const sourceBreakpoint = this._model - .getBreakpoints() - .filter(b => b.idFromAdapter === breakpoint.id) - .pop(); - const functionBreakpoint = this._model - .getFunctionBreakpoints() - .filter(b => b.idFromAdapter === breakpoint.id) - .pop(); - if (sourceBreakpoint == null && functionBreakpoint == null) { - return Observable.empty(); - } else { - return Observable.of({ - reason, - breakpoint, - sourceBreakpoint, - functionBreakpoint, - }); - } - }) - .take(1) - .timeout(MAX_BREAKPOINT_EVENT_DELAY_MS) - .catch(error => { - if (error instanceof TimeoutError) { - logger.error( - 'Timed out breakpoint event handler', - process.configuration.adapterType, - reason, - breakpoint, - ); - } - return Observable.empty(); - }); - }) - .subscribe( - ({reason, breakpoint, sourceBreakpoint, functionBreakpoint}) => { - if (reason === BreakpointEventReasons.NEW && breakpoint.source) { - const source = process.getSource(breakpoint.source); - const bps = this._model.addBreakpoints( - source.uri, - [ - { - column: breakpoint.column || 0, - enabled: true, - line: breakpoint.line == null ? -1 : breakpoint.line, - }, - ], - false, - ); - if (bps.length === 1) { - this._model.updateBreakpoints({ - [bps[0].getId()]: breakpoint, - }); - } - } else if (reason === BreakpointEventReasons.REMOVED) { - if (sourceBreakpoint != null) { - this._model.removeBreakpoints([sourceBreakpoint]); - } - if (functionBreakpoint != null) { - this._model.removeFunctionBreakpoints( - functionBreakpoint.getId(), - ); - } - } else if (reason === BreakpointEventReasons.CHANGED) { - if (sourceBreakpoint != null) { - if (!sourceBreakpoint.column) { - breakpoint.column = undefined; - } - this._model.updateBreakpoints({ - [sourceBreakpoint.getId()]: breakpoint, - }); - } - if (functionBreakpoint != null) { - this._model.updateFunctionBreakpoints({ - [functionBreakpoint.getId()]: breakpoint, - }); - } - } else { - logger.warn('Unknown breakpoint event', reason, breakpoint); - } - }, - ), - ); - - this._sessionEndDisposables.add( - session.observeAdapterExitedEvents().subscribe(event => { - // 'Run without debugging' mode VSCode must terminate the extension host. More details: #3905 - this._onSessionEnd(); - }), - ); - - this._sessionEndDisposables.add( - session.observeCustomEvents().subscribe(event => { - this._emitter.emit(CUSTOM_DEBUG_EVENT, event); - }), - ); - - // Clear in memory breakpoints. - this._sessionEndDisposables.add(() => { - const sourceRefBreakpoints = this._model - .getBreakpoints() - .filter(bp => bp.uri.startsWith(DEBUG_SOURCES_URI)); - if (sourceRefBreakpoints.length > 0) { - this._model.removeBreakpoints(sourceRefBreakpoints); - } - }); - } - _scheduleNativeNotification(): void { - const raiseNativeNotification = getNotificationService(); - if (raiseNativeNotification != null) { - const pendingNotification = raiseNativeNotification( - 'Debugger', - 'Paused at a breakpoint', - 3000, - false, - ); - if (pendingNotification != null) { - this._sessionEndDisposables.add(pendingNotification); - } - } - } - onDidCustomEvent( - callback: (event: DebugProtocol.DebugEvent) => mixed, - ): IDisposable { - return this._emitter.on(CUSTOM_DEBUG_EVENT, callback); - } - onDidChangeMode(callback: (mode: DebuggerModeType) => mixed): IDisposable { - return this._emitter.on(CHANGE_DEBUG_MODE, callback); - } - _loadBreakpoints(state: ?SerializedState): Breakpoint[] { - let result: Breakpoint[] = []; - if (state == null || state.sourceBreakpoints == null) { - return result; - } - try { - result = state.sourceBreakpoints.map(breakpoint => { - return new Breakpoint( - breakpoint.uri, - breakpoint.line, - breakpoint.column, - breakpoint.enabled, - breakpoint.condition, - breakpoint.hitCondition, - breakpoint.adapterData, - ); - }); - } catch (e) {} - return result; - } - _loadFunctionBreakpoints(state: ?SerializedState): FunctionBreakpoint[] { - let result: FunctionBreakpoint[] = []; - if (state == null || state.functionBreakpoints == null) { - return result; - } - try { - result = state.functionBreakpoints.map(fb => { - return new FunctionBreakpoint(fb.name, fb.enabled, fb.hitCondition); - }); - } catch (e) {} - return result; - } - _loadExceptionBreakpoints(state: ?SerializedState): ExceptionBreakpoint[] { - let result: ExceptionBreakpoint[] = []; - if (state == null || state.exceptionBreakpoints == null) { - return result; - } - try { - result = state.exceptionBreakpoints.map(exBreakpoint => { - return new ExceptionBreakpoint( - exBreakpoint.filter, - exBreakpoint.label, - exBreakpoint.enabled, - ); - }); - } catch (e) {} - return result; - } - _loadWatchExpressions(state: ?SerializedState): Expression[] { - let result: Expression[] = []; - if (state == null || state.watchExpressions == null) { - return result; - } - try { - result = state.watchExpressions.map(name => new Expression(name)); - } catch (e) {} - return result; - } - _updateModeAndEmit(debugMode: DebuggerModeType): void { - this._debuggerMode = debugMode; - this._emitter.emit(CHANGE_DEBUG_MODE, debugMode); - } - focusStackFrame( - stackFrame: ?IStackFrame, - thread: ?IThread, - process: ?IProcess, - explicit?: boolean = false, - ): void { - let focusProcess = process; - if (focusProcess == null) { - if (stackFrame != null) { - focusProcess = stackFrame.thread.process; - } else if (thread != null) { - focusProcess = thread.process; - } else { - focusProcess = this._model.getProcesses()[0]; - } - } - let focusThread: ?IThread = thread; - let focusStackFrame = stackFrame; - if (focusThread == null && stackFrame != null) { - focusThread = stackFrame.thread; - } else if (focusThread != null && focusProcess != null) { - focusThread = focusProcess.getThread(focusThread.threadId); - } - if (stackFrame == null && thread != null) { - focusStackFrame = thread.getCallStack()[0]; - } - this._viewModel.setFocus( - focusStackFrame, - focusThread, - focusProcess, - explicit, - ); - this._updateModeAndEmit(this._computeDebugMode()); - } - _computeDebugMode(): DebuggerModeType { - const {focusedThread, focusedStackFrame} = this._viewModel; - if ( - focusedStackFrame != null || - (focusedThread != null && focusedThread.stopped) - ) { - return DebuggerMode.PAUSED; - } else if (this._getCurrentProcess() == null) { - return DebuggerMode.STOPPED; - } else { - return DebuggerMode.RUNNING; - } - } - enableOrDisableBreakpoints( - enable: boolean, - breakpoint?: IEnableable, - ): Promise { - if (breakpoint != null) { - this._model.setEnablement(breakpoint, enable); - if (breakpoint instanceof Breakpoint) { - return this._sendBreakpoints(breakpoint.uri); - } else if (breakpoint instanceof FunctionBreakpoint) { - return this._sendFunctionBreakpoints(); - } else { - track(AnalyticsEvents.DEBUGGER_TOGGLE_EXCEPTION_BREAKPOINT); - return this._sendExceptionBreakpoints(); - } - } - this._model.enableOrDisableAllBreakpoints(enable); - return this._sendAllBreakpoints(); - } - addBreakpoints(uri: string, rawBreakpoints: IRawBreakpoint[]): Promise { - track(AnalyticsEvents.DEBUGGER_BREAKPOINT_ADD); - this._model.addBreakpoints(uri, rawBreakpoints); - return this._sendBreakpoints(uri); - } - toggleSourceBreakpoint(uri: string, line: number): Promise { - track(AnalyticsEvents.DEBUGGER_BREAKPOINT_TOGGLE); - const existing = this._model.getBreakpointAtLine(uri, line); - if (existing == null) { - return this.addBreakpoints(uri, [{line}]); - } else { - return this.removeBreakpoints(existing.getId(), true); - } - } - updateBreakpoints( - uri: string, - data: {[id: string]: DebugProtocol.Breakpoint}, - ) { - this._model.updateBreakpoints(data); - this._breakpointsToSendOnSave.add(uri); - } - async removeBreakpoints( - id?: string, - skipAnalytics?: boolean = false, - ): Promise { - const toRemove = this._model - .getBreakpoints() - .filter(bp => id == null || bp.getId() === id); - const urisToClear = distinct(toRemove, bp => bp.uri).map(bp => bp.uri); - - this._model.removeBreakpoints(toRemove); - - if (id == null) { - track(AnalyticsEvents.DEBUGGER_BREAKPOINT_DELETE_ALL); - } else if (!skipAnalytics) { - track(AnalyticsEvents.DEBUGGER_BREAKPOINT_DELETE); - } - await Promise.all(urisToClear.map(uri => this._sendBreakpoints(uri))); - } - setBreakpointsActivated(activated: boolean): Promise { - this._model.setBreakpointsActivated(activated); - return this._sendAllBreakpoints(); - } - addFunctionBreakpoint(): void { - this._model.addFunctionBreakpoint(''); - } - renameFunctionBreakpoint(id: string, newFunctionName: string): Promise { - this._model.updateFunctionBreakpoints({[id]: {name: newFunctionName}}); - return this._sendFunctionBreakpoints(); - } - removeFunctionBreakpoints(id?: string): Promise { - this._model.removeFunctionBreakpoints(id); - return this._sendFunctionBreakpoints(); - } - async terminateThreads(threadIds: Array): Promise { - const {focusedProcess} = this.viewModel; - if (focusedProcess == null) { - return; - } - const session = focusedProcess.session; - track(AnalyticsEvents.DEBUGGER_TERMINATE_THREAD); - if (Boolean(session.capabilities.supportsTerminateThreadsRequest)) { - await session.custom('terminateThreads', { - threadIds, - }); - } - } - async runToLocation(uri: string, line: number): Promise { - const {focusedThread, focusedProcess} = this.viewModel; - if (focusedThread == null || focusedProcess == null) { - return; - } - const session = focusedProcess.session; - track(AnalyticsEvents.DEBUGGER_STEP_RUN_TO_LOCATION); - if (Boolean(session.capabilities.supportsContinueToLocation)) { - await session.custom('continueToLocation', { - source: focusedProcess.getSource({path: uri}).raw, - line, - threadId: focusedThread.threadId, - }); - return; - } - const existing = this._model.getBreakpointAtLine(uri, line); - if (existing == null) { - await this.addBreakpoints(uri, [{line}]); - const runToLocationBreakpoint = this._model.getBreakpointAtLine( - uri, - line, - ); - invariant(runToLocationBreakpoint != null); - - const removeBreakpoint = () => { - this.removeBreakpoints( - runToLocationBreakpoint.getId(), - true /* skip analytics */, - ).catch(error => - onUnexpectedError( - `Failed to clear run-to-location breakpoint! - ${String(error)}`, - ), - ); - removeBreakpointDisposable.dispose(); - this._sessionEndDisposables.remove(removeBreakpointDisposable); - this._sessionEndDisposables.remove(removeBreakpoint); - }; - - // Remove if the debugger stopped at any location. - const removeBreakpointDisposable = new UniversalDisposable( - session - .observeStopEvents() - .take(1) - .subscribe(removeBreakpoint), - ); - // Remove if the session has ended without hitting it. - this._sessionEndDisposables.add( - removeBreakpointDisposable, - removeBreakpoint, - ); - } - await focusedThread.continue(); - } - addWatchExpression(name: string): void { - track(AnalyticsEvents.DEBUGGER_WATCH_ADD_EXPRESSION); - return this._model.addWatchExpression(name); - } - renameWatchExpression(id: string, newName: string): void { - track(AnalyticsEvents.DEBUGGER_WATCH_UPDATE_EXPRESSION); - return this._model.renameWatchExpression(id, newName); - } - removeWatchExpressions(id?: string): void { - track(AnalyticsEvents.DEBUGGER_WATCH_REMOVE_EXPRESSION); - this._model.removeWatchExpressions(id); - } - createExpression(rawExpression: string): IEvaluatableExpression { - return new Expression(rawExpression); - } - async _doCreateProcess( - rawConfiguration: IProcessConfig, - sessionId: string, - ): Promise { - const errorHandler = (error: Error) => { - if (this._timer != null) { - this._timer.onError(error); - this._timer = null; - } - track(AnalyticsEvents.DEBUGGER_START_FAIL, {}); - const errorMessage = error instanceof Error ? error.message : error; - atom.notifications.addError( - `Failed to start debugger process: ${errorMessage}`, - ); - this._consoleDisposables.dispose(); - this._updateModeAndEmit(DebuggerMode.STOPPED); - if (!session.isDisconnected()) { - this._onSessionEnd(); - session.disconnect().catch(onUnexpectedError); - } - if (process != null) { - this._model.removeProcess(process.getId()); - } - }; - let process: ?IProcess; - - const adapterExecutable = await this._resolveAdapterExecutable( - rawConfiguration, - ); - const configuration = await resolveDebugConfiguration({ - ...rawConfiguration, - adapterExecutable, - }); - - track(AnalyticsEvents.DEBUGGER_START, { - serviceName: configuration.adapterType, - clientType: 'VSP', - }); - - const session = await this._createVsDebugSession( - configuration, - adapterExecutable, - sessionId, - ); - try { - process = this._model.addProcess(configuration, session); - this.focusStackFrame(null, null, process); - this._registerSessionListeners(process, session); - atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'debugger:show', - ); - await session.initialize({ - clientID: 'atom', - adapterID: configuration.adapterType, - pathFormat: 'path', - linesStartAt1: true, - columnsStartAt1: true, - supportsVariableType: true, - supportsVariablePaging: false, - supportsRunInTerminalRequest: getTerminalService() != null, - locale: 'en-us', - }); - this._model.setExceptionBreakpoints( - session.getCapabilities().exceptionBreakpointFilters || [], - ); - // We're not awaiting launch/attach to finish because some debug adapters - // need to do custom work for launch/attach to work (e.g. mobilejs) - this._launchOrAttachTarget(session, configuration).catch(errorHandler); - return process; - } catch (error) { - errorHandler(error); - return null; - } - } - async _resolveAdapterExecutable( - configuration: IProcessConfig, - ): Promise { - if (configuration.adapterExecutable != null) { - return configuration.adapterExecutable; - } - return getVSCodeDebuggerAdapterServiceByNuclideUri( - configuration.targetUri, - ).getAdapterExecutableInfo(configuration.adapterType); - } - async _createVsDebugSession( - configuration: IProcessConfig, - adapterExecutable: VSAdapterExecutableInfo, - sessionId: string, - ): Promise { - const {targetUri} = configuration; - const service = getVSCodeDebuggerAdapterServiceByNuclideUri(targetUri); - const spawner = new service.VsRawAdapterSpawnerService(); - - const clientPreprocessors: Array = []; - const adapterPreprocessors: Array = []; - if (configuration.clientPreprocessor != null) { - clientPreprocessors.push(configuration.clientPreprocessor); - } - if (configuration.adapterPreprocessor != null) { - adapterPreprocessors.push(configuration.adapterPreprocessor); - } - const isRemote = nuclideUri.isRemote(targetUri); - if (isRemote) { - clientPreprocessors.push(remoteToLocalProcessor()); - adapterPreprocessors.push(localToRemoteProcessor(targetUri)); - } - return new VsDebugSession( - sessionId, - logger, - adapterExecutable, - {adapter: configuration.adapterType, host: 'debugService', isRemote}, - spawner, - clientPreprocessors, - adapterPreprocessors, - this._runInTerminal, - ); - } - async _launchOrAttachTarget( - session: VsDebugSession, - configuration: IProcessConfig, - ): Promise { - if (configuration.debugMode === 'attach') { - await session.attach(configuration.config); - } else { - // It's 'launch' - await session.launch(configuration.config); - } - if (!session.isDisconnected()) { - this._updateModeAndEmit(DebuggerMode.RUNNING); - } - } - _sourceIsNotAvailable(uri: string): void { - this._model.sourceIsNotAvailable(uri); - } - _runInTerminal = async ( - args: DebugProtocol.RunInTerminalRequestArguments, - ): Promise => { - const terminalService = getTerminalService(); - if (terminalService == null) { - throw new Error( - 'Unable to launch in terminal since the service is not available', - ); - } - const process = this._getCurrentProcess(); - if (process == null) { - throw new Error("There's no debug process to create a terminal for!"); - } - const {adapterType, targetUri} = process.configuration; - const key = `targetUri=${targetUri}&command=${args.args[0]}`; - - // Ensure any previous instances of this same target are closed before - // opening a new terminal tab. We don't want them to pile up if the - // user keeps running the same app over and over. - terminalService.close(key); - - const title = - args.title != null ? args.title : getDebuggerName(adapterType); - const hostname = nuclideUri.getHostnameOpt(targetUri); - const cwd = - hostname == null - ? args.cwd - : nuclideUri.createRemoteUri(hostname, args.cwd); - - const info: TerminalInfo = { - key, - title, - cwd, - command: { - file: args.args[0], - args: args.args.slice(1), - }, - environmentVariables: - args.env != null ? mapFromObject(args.env) : undefined, - preservedCommands: [ - 'debugger:continue-debugging', - 'debugger:stop-debugging', - 'debugger:restart-debugging', - 'debugger:step-over', - 'debugger:step-into', - 'debugger:step-out', - ], - remainOnCleanExit: true, - icon: 'nuclicon-debugger', - defaultLocation: 'bottom', - }; - const terminal = await terminalService.open(info); - terminal.setProcessExitCallback(() => { - // This callback is invoked if the target process dies first, ensuring - // we tear down the debugger. - this.stopProcess(); - }); - - this._sessionEndDisposables.add(() => { - // This termination path is invoked if the debugger dies first, ensuring - // we terminate the target process. This can happen if the user hits stop, - // or if the debugger crashes. - terminal.setProcessExitCallback(() => {}); - terminal.terminateProcess(); - }); - }; - - async restartProcess(): Promise { - const process = this._getCurrentProcess(); - if (process == null) { - return; - } - if (process.session.capabilities.supportsRestartRequest) { - await process.session.custom('restart', null); - } - await process.session.disconnect(true); - await sleep(300); - await this.startDebugging(process.configuration); - } - /** - * Starts debugging. If the configOrName is not passed uses the selected configuration in the debug dropdown. - * Also saves all files, manages if compounds are present in the configuration - * and resolveds configurations via DebugConfigurationProviders. - */ - async startDebugging(config: IProcessConfig): Promise { - this._timer = startTracking('debugger-atom:startDebugging'); - if (this._viewModel.focusedProcess != null) { - // We currently support only running only one debug session at a time. - notifyOpenDebugSession(); - return; - } - this._updateModeAndEmit(DebuggerMode.STARTING); - // Open the console window if it's not already opened. - // eslint-disable-next-line rulesdir/atom-apis - atom.workspace.open(CONSOLE_VIEW_URI, {searchAllPanes: true}); - this._consoleDisposables = this._registerConsoleExecutor(); - await this._doCreateProcess(config, uuid.v4()); - } - _onSessionEnd = (): void => { - const session = this._getCurrentSession(); - if (session == null) { - return; - } - track(AnalyticsEvents.DEBUGGER_STOP); - this._model.removeProcess(session.getId()); - this._sessionEndDisposables.dispose(); - this._consoleDisposables.dispose(); - if (this._timer != null) { - this._timer.onSuccess(); - this._timer = null; - } - this.focusStackFrame(null, null, null); - this._updateModeAndEmit(DebuggerMode.STOPPED); - - // set breakpoints back to unverified since the session ended. - const data: { - [id: string]: DebugProtocol.Breakpoint, - } = {}; - this._model.getBreakpoints().forEach(bp => { - data[bp.getId()] = { - line: bp.line, - verified: false, - column: bp.column, - endLine: bp.endLine == null ? undefined : bp.endLine, - endColumn: bp.endColumn == null ? undefined : bp.endColumn, - }; - }); - this._model.updateBreakpoints(data); - }; - - getModel(): IModel { - return this._model; - } - async _sendAllBreakpoints(): Promise { - await Promise.all( - distinct(this._model.getBreakpoints(), bp => bp.uri).map(bp => - this._sendBreakpoints(bp.uri, false), - ), - ); - await this._sendFunctionBreakpoints(); - // send exception breakpoints at the end since some debug adapters rely on the order - await this._sendExceptionBreakpoints(); - } - async _sendBreakpoints( - uri: string, - sourceModified?: boolean = false, - ): Promise { - const process = this._getCurrentProcess(); - const session = this._getCurrentSession(); - if ( - process == null || - session == null || - !session.isReadyForBreakpoints() - ) { - return; - } - const breakpointsToSend = this._model - .getBreakpoints() - .filter( - bp => - this._model.areBreakpointsActivated() && bp.enabled && bp.uri === uri, - ); - const rawSource = process.getSource({ - path: uri, - name: nuclideUri.basename(uri), - }).raw; - if (breakpointsToSend.length && !rawSource.adapterData) { - rawSource.adapterData = breakpointsToSend[0].adapterData; - } - // The UI is 0-based, while VSP is 1-based. - const response = await session.setBreakpoints({ - source: (rawSource: any), - lines: breakpointsToSend.map(bp => bp.line), - breakpoints: breakpointsToSend.map(bp => ({ - line: bp.line, - column: bp.column, - condition: bp.condition, - hitCondition: bp.hitCondition, - })), - sourceModified, - }); - if (response == null || response.body == null) { - return; - } - const data: {[id: string]: DebugProtocol.Breakpoint} = {}; - for (let i = 0; i < breakpointsToSend.length; i++) { - data[breakpointsToSend[i].getId()] = response.body.breakpoints[i]; - if (!breakpointsToSend[i].column) { - // If there was no column sent ignore the breakpoint column response from the adapter - data[breakpointsToSend[i].getId()].column = undefined; + + + + + + + + + + + + + + _runInTerminal = (() => {var _ref3 = (0, _asyncToGenerator.default)(function* ( + args) + { + const terminalService = (0, (_AtomServiceContainer || _load_AtomServiceContainer()).getTerminalService)(); + if (terminalService == null) { + throw new Error( + 'Unable to launch in terminal since the service is not available'); + + } + const process = _this._getCurrentProcess(); + if (process == null) { + throw new Error("There's no debug process to create a terminal for!"); + } + const { adapterType, targetUri } = process.configuration; + const key = `targetUri=${targetUri}&command=${args.args[0]}`; + + // Ensure any previous instances of this same target are closed before + // opening a new terminal tab. We don't want them to pile up if the + // user keeps running the same app over and over. + terminalService.close(key); + + const title = + args.title != null ? args.title : getDebuggerName(adapterType); + const hostname = (_nuclideUri || _load_nuclideUri()).default.getHostnameOpt(targetUri); + const cwd = + hostname == null ? + args.cwd : + (_nuclideUri || _load_nuclideUri()).default.createRemoteUri(hostname, args.cwd); + + const info = { + key, + title, + cwd, + command: { + file: args.args[0], + args: args.args.slice(1) }, + + environmentVariables: + args.env != null ? (0, (_collection || _load_collection()).mapFromObject)(args.env) : undefined, + preservedCommands: [ + 'debugger:continue-debugging', + 'debugger:stop-debugging', + 'debugger:restart-debugging', + 'debugger:step-over', + 'debugger:step-into', + 'debugger:step-out'], + + remainOnCleanExit: true, + icon: 'nuclicon-debugger', + defaultLocation: 'bottom' }; + + const terminal = yield terminalService.open(info); + terminal.setProcessExitCallback(function () { + // This callback is invoked if the target process dies first, ensuring + // we tear down the debugger. + _this.stopProcess(); + }); + + _this._sessionEndDisposables.add(function () { + // This termination path is invoked if the debugger dies first, ensuring + // we terminate the target process. This can happen if the user hits stop, + // or if the debugger crashes. + terminal.setProcessExitCallback(function () {}); + terminal.terminateProcess(); + }); + });return function (_x) {return _ref3.apply(this, arguments);};})();this. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _onSessionEnd = () => { + const session = this._getCurrentSession(); + if (session == null) { + return; + } + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_STOP); + this._model.removeProcess(session.getId()); + this._sessionEndDisposables.dispose(); + this._consoleDisposables.dispose(); + if (this._timer != null) { + this._timer.onSuccess(); + this._timer = null; + } + + this.focusStackFrame(null, null, null); + this._updateModeAndEmit((_constants || _load_constants()).DebuggerMode.STOPPED); + + // set breakpoints back to unverified since the session ended. + const data = + + {}; + this._model.getBreakpoints().forEach(bp => { + data[bp.getId()] = { + line: bp.line, + verified: false, + column: bp.column, + endLine: bp.endLine == null ? undefined : bp.endLine, + endColumn: bp.endColumn == null ? undefined : bp.endColumn }; + + }); + this._model.updateBreakpoints(data); + };this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default();this._sessionEndDisposables = new (_UniversalDisposable || _load_UniversalDisposable()).default();this._consoleDisposables = new (_UniversalDisposable || _load_UniversalDisposable()).default();this._emitter = new _atom.Emitter();this._debuggerMode = (_constants || _load_constants()).DebuggerMode.STOPPED;this._viewModel = new ViewModel();this._breakpointsToSendOnSave = new Set();this._model = new (_DebuggerModel || _load_DebuggerModel()).Model(this._loadBreakpoints(state), true, this._loadFunctionBreakpoints(state), this._loadExceptionBreakpoints(state), this._loadWatchExpressions(state));this._disposables.add(this._model);this._registerListeners();}get viewModel() {return this._viewModel;}getDebuggerMode() {return this._debuggerMode;}_registerListeners() {this._disposables.add(atom.workspace.addOpener(uri => {if (uri.startsWith((_constants || _load_constants()).DEBUG_SOURCES_URI)) {if (this._debuggerMode !== (_constants || _load_constants()).DebuggerMode.STOPPED) {return this._openSourceView(uri);} else {throw new Error('Cannot open debug source views - no active debug session');}}}));}_openSourceView(uri) {var _this2 = this;return (0, _asyncToGenerator.default)(function* () {const query = (_url.default.parse(uri).path || '').split('/');const [, sessionId, sourceReferenceRaw] = query;const sourceReference = parseInt(sourceReferenceRaw, 10);const process = _this2._model.getProcesses().find(function (p) {return p.getId() === sessionId;}) || _this2._viewModel.focusedProcess;if (process == null) {throw new Error(`No debug session for source: ${sourceReference}`);}const source = process.getSource({ path: uri, sourceReference });let content = '';try {const response = yield process.session.source({ sourceReference, source: source.raw });content = response.body.content;} catch (error) {_this2._sourceIsNotAvailable(uri);throw new Error('Debug source is not available');}const editor = atom.workspace.buildTextEditor({ buffer: new DebugSourceTextBufffer(content, uri), autoHeight: false, readOnly: true }); // $FlowFixMe Debugger source views shouldn't persist between reload. + editor.serialize = function () {return null;};editor.setGrammar(atom.grammars.selectGrammar(source.name || '', content));const textEditorBanner = new (_TextEditorBanner || _load_TextEditorBanner()).TextEditorBanner(editor);textEditorBanner.render(_react.createElement((_ReadOnlyNotice || _load_ReadOnlyNotice()).default, { detailedMessage: 'This is a debug source view that may not exist on the filesystem.', canEditAnyway: false, onDismiss: textEditorBanner.dispose.bind(textEditorBanner) }));const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(textEditorBanner, editor.onDidDestroy(function () {return disposable.dispose();}), function () {return editor.destroy();});_this2._sessionEndDisposables.add(disposable);return editor;})();} /** + * Stops the process. If the process does not exist then stops all processes. + */stopProcess() {var _this3 = this;return (0, _asyncToGenerator.default)(function* () {if (_this3._debuggerMode === (_constants || _load_constants()).DebuggerMode.STOPPING || _this3._debuggerMode === (_constants || _load_constants()).DebuggerMode.STOPPED) {return;}_this3._onSessionEnd();})();}_tryToAutoFocusStackFrame(thread) {const callStack = thread.getCallStack();if (callStack.length === 0 || this._viewModel.focusedStackFrame && this._viewModel.focusedStackFrame.thread.getId() === thread.getId() && callStack.includes(this._viewModel.focusedStackFrame)) {return;} // Focus first stack frame from top that has source location if no other stack frame is focused + const stackFrameToFocus = callStack.find(sf => sf.source != null && sf.source.available);if (stackFrameToFocus == null) {return;}this.focusStackFrame(stackFrameToFocus, null, null);}_registerMarkers() {let selectedFrameMarker = null;let threadChangeDatatip;let lastFocusedThreadId;const cleaupMarkers = () => {if (selectedFrameMarker != null) {selectedFrameMarker.destroy();selectedFrameMarker = null;}if (threadChangeDatatip != null) {threadChangeDatatip.dispose();threadChangeDatatip = null;}};return new (_UniversalDisposable || _load_UniversalDisposable()).default((0, (_event || _load_event()).observableFromSubscribeFunction)(this._viewModel.onDidFocusStackFrame.bind(this._viewModel)).concatMap(event => {cleaupMarkers();const { stackFrame, explicit } = event;if (stackFrame == null || !stackFrame.source.available) {if (explicit) {atom.notifications.addWarning('No source available for the selected stack frame');}return _rxjsBundlesRxMinJs.Observable.empty();}return _rxjsBundlesRxMinJs.Observable.fromPromise(stackFrame.openInEditor()).switchMap(editor => {if (editor == null) {atom.notifications.addError('Failed to open source file for stack frame!');return _rxjsBundlesRxMinJs.Observable.empty();}return _rxjsBundlesRxMinJs.Observable.of({ editor, explicit, stackFrame });});}).subscribe(({ editor, explicit, stackFrame }) => {const line = stackFrame.range.start.row;selectedFrameMarker = editor.markBufferRange([[line, 0], [line, Infinity]], { invalidate: 'never' });editor.decorateMarker(selectedFrameMarker, { type: 'line', class: 'debugger-current-line-highlight' });const datatipService = (0, (_AtomServiceContainer || _load_AtomServiceContainer()).getDatatipService)();if (datatipService == null) {return;}if (lastFocusedThreadId != null && !explicit && stackFrame.thread.threadId !== lastFocusedThreadId) {const message = `Active thread changed from ${lastFocusedThreadId} to ${stackFrame.thread.threadId}`;threadChangeDatatip = datatipService.createPinnedDataTip({ component: () => _react.createElement('div', { className: 'debugger-thread-switch-alert' }, _react.createElement((_Icon || _load_Icon()).Icon, { icon: 'alert' }), message), range: stackFrame.range, pinnable: true }, editor);}lastFocusedThreadId = stackFrame.thread.threadId;}), cleaupMarkers);}_registerSessionListeners(process, session) {var _this4 = this;this._sessionEndDisposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(session);this._sessionEndDisposables.add(this._registerMarkers());const sessionId = session.getId();const threadFetcher = (0, (_promise || _load_promise()).serializeAsyncCall)((0, _asyncToGenerator.default)(function* () {const response = yield session.threads();if (response && response.body && response.body.threads) {response.body.threads.forEach(function (thread) {_this4._model.rawUpdate({ sessionId, thread });});}}));const openFilesSaved = (0, (_event || _load_event()).observableFromSubscribeFunction)(atom.workspace.observeTextEditors.bind(atom.workspace)).flatMap(editor => {return (0, (_event || _load_event()).observableFromSubscribeFunction)(editor.onDidSave.bind(editor)).map(() => editor.getPath()).takeUntil((0, (_event || _load_event()).observableFromSubscribeFunction)(editor.onDidDestroy.bind(editor)));});this._sessionEndDisposables.add(openFilesSaved.subscribe((() => {var _ref5 = (0, _asyncToGenerator.default)(function* (filePath) {if (filePath == null || !_this4._breakpointsToSendOnSave.has(filePath)) {return;}_this4._breakpointsToSendOnSave.delete(filePath);yield _this4._sendBreakpoints(filePath, true);});return function (_x2) {return _ref5.apply(this, arguments);};})()));this._sessionEndDisposables.add(session.observeInitializeEvents().subscribe((() => {var _ref6 = (0, _asyncToGenerator.default)(function* (event) {const sendConfigurationDone = (() => {var _ref7 = (0, _asyncToGenerator.default)(function* () {if (session && session.getCapabilities().supportsConfigurationDoneRequest) {return session.configurationDone().catch(function (e) {// Disconnect the debug session on configuration done error #10596 + _this4._onSessionEnd();session.disconnect().catch((_utils || _load_utils()).onUnexpectedError);atom.notifications.addError('Failed to configure debugger', { detail: e.message });});}});return function sendConfigurationDone() {return _ref7.apply(this, arguments);};})();try {yield _this4._sendAllBreakpoints().then(sendConfigurationDone, sendConfigurationDone);yield threadFetcher();} catch (error) {(0, (_utils || _load_utils()).onUnexpectedError)(error);}});return function (_x3) {return _ref6.apply(this, arguments);};})()));const toFocusThreads = new _rxjsBundlesRxMinJs.Subject();const observeContinuedTo = threadId => {return session.observeContinuedEvents().filter(continued => continued.body.allThreadsContinued || threadId != null && threadId === continued.body.threadId).take(1);};this._sessionEndDisposables.add(session.observeStopEvents().subscribe(() => {this._updateModeAndEmit((_constants || _load_constants()).DebuggerMode.PAUSED);}), session.observeStopEvents().flatMap(event => _rxjsBundlesRxMinJs.Observable.fromPromise(threadFetcher()).ignoreElements().concat(_rxjsBundlesRxMinJs.Observable.of(event)).catch(error => {(0, (_utils || _load_utils()).onUnexpectedError)(error);return _rxjsBundlesRxMinJs.Observable.empty();}) // Proceeed processing the stopped event only if there wasn't + // a continued event while we're fetching the threads + .takeUntil(observeContinuedTo(event.body.threadId))).subscribe(event => {const { threadId } = event.body; // Updating stopped state needs to happen after fetching the threads + this._model.rawUpdate({ sessionId, stoppedDetails: event.body, threadId });if (threadId == null) {return;}const thread = process.getThread(threadId);if (thread != null) {toFocusThreads.next(thread);}}), toFocusThreads.concatMap(thread => {var _ref, _ref2;const { focusedThread } = this._viewModel;const preserveFocusHint = ((_ref = thread) != null ? (_ref2 = _ref.stoppedDetails) != null ? _ref2.preserveFocusHint : _ref2 : _ref) || false;if (focusedThread != null && focusedThread.stopped && focusedThread.getId() !== thread.getId() && preserveFocusHint) {// The debugger is already stopped elsewhere. + return _rxjsBundlesRxMinJs.Observable.empty();} // UX: That'll fetch the top stack frame first (to allow the UI to focus on it), + // then the rest of the call stack. + return _rxjsBundlesRxMinJs.Observable.fromPromise(this._model.fetchCallStack(thread)).ignoreElements().concat(_rxjsBundlesRxMinJs.Observable.of(thread)) // Avoid focusing a continued thread. + .takeUntil(observeContinuedTo(thread.threadId)) // Verify the thread is still stopped. + .filter(() => thread.stopped).catch(error => {(0, (_utils || _load_utils()).onUnexpectedError)(error);return _rxjsBundlesRxMinJs.Observable.empty();});}).subscribe(thread => {this._tryToAutoFocusStackFrame(thread);this._scheduleNativeNotification();}));this._sessionEndDisposables.add(session.observeThreadEvents().subscribe((() => {var _ref8 = (0, _asyncToGenerator.default)(function* (event) {if (event.body.reason === 'started') {yield threadFetcher();} else if (event.body.reason === 'exited') {_this4._model.clearThreads(session.getId(), true, event.body.threadId);}});return function (_x4) {return _ref8.apply(this, arguments);};})()));this._sessionEndDisposables.add(session.observeTerminateDebugeeEvents().subscribe(event => {if (event.body && event.body.restart) {this.restartProcess().catch(err => {atom.notifications.addError('Failed to restart debugger', { detail: err.stack || String(err) });});} else {this._onSessionEnd();session.disconnect().catch((_utils || _load_utils()).onUnexpectedError);}}));this._sessionEndDisposables.add(session.observeContinuedEvents().subscribe(event => {const threadId = event.body.allThreadsContinued !== false ? undefined : event.body.threadId;this._model.clearThreads(session.getId(), false, threadId);this.focusStackFrame(null, this._viewModel.focusedThread, null);this._updateModeAndEmit(this._computeDebugMode());}));const createConsole = (0, (_AtomServiceContainer || _load_AtomServiceContainer()).getConsoleService)();if (createConsole != null) {const name = getDebuggerName(process.configuration.adapterType);const consoleApi = createConsole({ id: name, name });this._sessionEndDisposables.add(consoleApi);const outputEvents = session.observeOutputEvents().filter(event => event.body != null && typeof event.body.output === 'string').share();const KNOWN_CATEGORIES = new Set(['stderr', 'console', 'telemetry', 'success']);const logStream = (0, (_observable || _load_observable()).splitStream)(outputEvents.filter(e => !KNOWN_CATEGORIES.has(e.body.category)).map(e => (0, (_stripAnsi || _load_stripAnsi()).default)(e.body.output)));const [errorStream, warningsStream, successStream] = ['stderr', 'console', 'success'].map(category => (0, (_observable || _load_observable()).splitStream)(outputEvents.filter(e => category === e.body.category).map(e => (0, (_stripAnsi || _load_stripAnsi()).default)(e.body.output))));const notificationStream = outputEvents.filter(e => e.body.category === 'nuclide_notification').map(e => ({ type: (0, (_nullthrows || _load_nullthrows()).default)(e.body.data).type, message: e.body.output }));this._sessionEndDisposables.add(errorStream.subscribe(line => {consoleApi.append({ text: line, level: 'error' });}), warningsStream.subscribe(line => {consoleApi.append({ text: line, level: 'warning' });}), successStream.subscribe(line => {consoleApi.append({ text: line, level: 'success' });}), logStream.subscribe(line => {consoleApi.append({ text: line, level: 'log' });}), notificationStream.subscribe(({ type, message }) => {atom.notifications.add(type, message);}) // TODO handle non string output (e.g. files & objects) + );}this._sessionEndDisposables.add(session.observeBreakpointEvents().flatMap(event => {const { breakpoint, reason } = event.body;if (reason !== (_constants || _load_constants()).BreakpointEventReasons.CHANGED && reason !== (_constants || _load_constants()).BreakpointEventReasons.REMOVED) {return _rxjsBundlesRxMinJs.Observable.of({ reason, breakpoint, sourceBreakpoint: null, functionBreakpoint: null });} // Breakpoint events may arrive sooner than their responses. + // Hence, we'll keep them cached and try re-processing on every change to the model's breakpoints + // for a set maximum time, then discard. + return (0, (_event || _load_event()).observableFromSubscribeFunction)(this._model.onDidChangeBreakpoints.bind(this._model)).startWith(null).switchMap(() => {const sourceBreakpoint = this._model.getBreakpoints().filter(b => b.idFromAdapter === breakpoint.id).pop();const functionBreakpoint = this._model.getFunctionBreakpoints().filter(b => b.idFromAdapter === breakpoint.id).pop();if (sourceBreakpoint == null && functionBreakpoint == null) {return _rxjsBundlesRxMinJs.Observable.empty();} else {return _rxjsBundlesRxMinJs.Observable.of({ reason, breakpoint, sourceBreakpoint, functionBreakpoint });}}).take(1).timeout(MAX_BREAKPOINT_EVENT_DELAY_MS).catch(error => {if (error instanceof _rxjsBundlesRxMinJs.TimeoutError) {(_logger || _load_logger()).default.error('Timed out breakpoint event handler', process.configuration.adapterType, reason, breakpoint);}return _rxjsBundlesRxMinJs.Observable.empty();});}).subscribe(({ reason, breakpoint, sourceBreakpoint, functionBreakpoint }) => {if (reason === (_constants || _load_constants()).BreakpointEventReasons.NEW && breakpoint.source) {const source = process.getSource(breakpoint.source);const bps = this._model.addBreakpoints(source.uri, [{ column: breakpoint.column || 0, enabled: true, line: breakpoint.line == null ? -1 : breakpoint.line }], false);if (bps.length === 1) {this._model.updateBreakpoints({ [bps[0].getId()]: breakpoint });}} else if (reason === (_constants || _load_constants()).BreakpointEventReasons.REMOVED) {if (sourceBreakpoint != null) {this._model.removeBreakpoints([sourceBreakpoint]);}if (functionBreakpoint != null) {this._model.removeFunctionBreakpoints(functionBreakpoint.getId());}} else if (reason === (_constants || _load_constants()).BreakpointEventReasons.CHANGED) {if (sourceBreakpoint != null) {if (!sourceBreakpoint.column) {breakpoint.column = undefined;}this._model.updateBreakpoints({ [sourceBreakpoint.getId()]: breakpoint });}if (functionBreakpoint != null) {this._model.updateFunctionBreakpoints({ [functionBreakpoint.getId()]: breakpoint });}} else {(_logger || _load_logger()).default.warn('Unknown breakpoint event', reason, breakpoint);}}));this._sessionEndDisposables.add(session.observeAdapterExitedEvents().subscribe(event => {// 'Run without debugging' mode VSCode must terminate the extension host. More details: #3905 + this._onSessionEnd();}));this._sessionEndDisposables.add(session.observeCustomEvents().subscribe(event => {this._emitter.emit(CUSTOM_DEBUG_EVENT, event);})); // Clear in memory breakpoints. + this._sessionEndDisposables.add(() => {const sourceRefBreakpoints = this._model.getBreakpoints().filter(bp => bp.uri.startsWith((_constants || _load_constants()).DEBUG_SOURCES_URI));if (sourceRefBreakpoints.length > 0) {this._model.removeBreakpoints(sourceRefBreakpoints);}});}_scheduleNativeNotification() {const raiseNativeNotification = (0, (_AtomServiceContainer || _load_AtomServiceContainer()).getNotificationService)();if (raiseNativeNotification != null) {const pendingNotification = raiseNativeNotification('Debugger', 'Paused at a breakpoint', 3000, false);if (pendingNotification != null) {this._sessionEndDisposables.add(pendingNotification);}}}onDidCustomEvent(callback) {return this._emitter.on(CUSTOM_DEBUG_EVENT, callback);}onDidChangeMode(callback) {return this._emitter.on(CHANGE_DEBUG_MODE, callback);}_loadBreakpoints(state) {let result = [];if (state == null || state.sourceBreakpoints == null) {return result;}try {result = state.sourceBreakpoints.map(breakpoint => {return new (_DebuggerModel || _load_DebuggerModel()).Breakpoint(breakpoint.uri, breakpoint.line, breakpoint.column, breakpoint.enabled, breakpoint.condition, breakpoint.hitCondition, breakpoint.adapterData);});} catch (e) {}return result;}_loadFunctionBreakpoints(state) {let result = [];if (state == null || state.functionBreakpoints == null) {return result;}try {result = state.functionBreakpoints.map(fb => {return new (_DebuggerModel || _load_DebuggerModel()).FunctionBreakpoint(fb.name, fb.enabled, fb.hitCondition);});} catch (e) {}return result;}_loadExceptionBreakpoints(state) {let result = [];if (state == null || state.exceptionBreakpoints == null) {return result;}try {result = state.exceptionBreakpoints.map(exBreakpoint => {return new (_DebuggerModel || _load_DebuggerModel()).ExceptionBreakpoint(exBreakpoint.filter, exBreakpoint.label, exBreakpoint.enabled);});} catch (e) {}return result;}_loadWatchExpressions(state) {let result = [];if (state == null || state.watchExpressions == null) {return result;}try {result = state.watchExpressions.map(name => new (_DebuggerModel || _load_DebuggerModel()).Expression(name));} catch (e) {}return result;}_updateModeAndEmit(debugMode) {this._debuggerMode = debugMode;this._emitter.emit(CHANGE_DEBUG_MODE, debugMode);}focusStackFrame(stackFrame, thread, process, explicit = false) {let focusProcess = process;if (focusProcess == null) {if (stackFrame != null) {focusProcess = stackFrame.thread.process;} else if (thread != null) {focusProcess = thread.process;} else {focusProcess = this._model.getProcesses()[0];}}let focusThread = thread;let focusStackFrame = stackFrame;if (focusThread == null && stackFrame != null) {focusThread = stackFrame.thread;} else if (focusThread != null && focusProcess != null) {focusThread = focusProcess.getThread(focusThread.threadId);}if (stackFrame == null && thread != null) {focusStackFrame = thread.getCallStack()[0];}this._viewModel.setFocus(focusStackFrame, focusThread, focusProcess, explicit);this._updateModeAndEmit(this._computeDebugMode());}_computeDebugMode() {const { focusedThread, focusedStackFrame } = this._viewModel;if (focusedStackFrame != null || focusedThread != null && focusedThread.stopped) {return (_constants || _load_constants()).DebuggerMode.PAUSED;} else if (this._getCurrentProcess() == null) {return (_constants || _load_constants()).DebuggerMode.STOPPED;} else {return (_constants || _load_constants()).DebuggerMode.RUNNING;}}enableOrDisableBreakpoints(enable, breakpoint) {if (breakpoint != null) {this._model.setEnablement(breakpoint, enable);if (breakpoint instanceof (_DebuggerModel || _load_DebuggerModel()).Breakpoint) {return this._sendBreakpoints(breakpoint.uri);} else if (breakpoint instanceof (_DebuggerModel || _load_DebuggerModel()).FunctionBreakpoint) {return this._sendFunctionBreakpoints();} else {(0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_TOGGLE_EXCEPTION_BREAKPOINT);return this._sendExceptionBreakpoints();}}this._model.enableOrDisableAllBreakpoints(enable);return this._sendAllBreakpoints();}addBreakpoints(uri, rawBreakpoints) {(0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_BREAKPOINT_ADD);this._model.addBreakpoints(uri, rawBreakpoints);return this._sendBreakpoints(uri);}toggleSourceBreakpoint(uri, line) {(0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_BREAKPOINT_TOGGLE);const existing = this._model.getBreakpointAtLine(uri, line);if (existing == null) {return this.addBreakpoints(uri, [{ line }]);} else {return this.removeBreakpoints(existing.getId(), true);}}updateBreakpoints(uri, data) {this._model.updateBreakpoints(data);this._breakpointsToSendOnSave.add(uri);}removeBreakpoints(id, skipAnalytics = false) {var _this5 = this;return (0, _asyncToGenerator.default)(function* () {const toRemove = _this5._model.getBreakpoints().filter(function (bp) {return id == null || bp.getId() === id;});const urisToClear = (0, (_collection || _load_collection()).distinct)(toRemove, function (bp) {return bp.uri;}).map(function (bp) {return bp.uri;});_this5._model.removeBreakpoints(toRemove);if (id == null) {(0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_BREAKPOINT_DELETE_ALL);} else if (!skipAnalytics) {(0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_BREAKPOINT_DELETE);}yield Promise.all(urisToClear.map(function (uri) {return _this5._sendBreakpoints(uri);}));})();}setBreakpointsActivated(activated) {this._model.setBreakpointsActivated(activated);return this._sendAllBreakpoints();}addFunctionBreakpoint() {this._model.addFunctionBreakpoint('');}renameFunctionBreakpoint(id, newFunctionName) {this._model.updateFunctionBreakpoints({ [id]: { name: newFunctionName } });return this._sendFunctionBreakpoints();}removeFunctionBreakpoints(id) {this._model.removeFunctionBreakpoints(id);return this._sendFunctionBreakpoints();}terminateThreads(threadIds) {var _this6 = this;return (0, _asyncToGenerator.default)(function* () {const { focusedProcess } = _this6.viewModel;if (focusedProcess == null) {return;}const session = focusedProcess.session;(0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_TERMINATE_THREAD);if (Boolean(session.capabilities.supportsTerminateThreadsRequest)) {yield session.custom('terminateThreads', { threadIds });}})();}runToLocation(uri, line) {var _this7 = this;return (0, _asyncToGenerator.default)(function* () {const { focusedThread, focusedProcess } = _this7.viewModel;if (focusedThread == null || focusedProcess == null) {return;}const session = focusedProcess.session;(0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_STEP_RUN_TO_LOCATION);if (Boolean(session.capabilities.supportsContinueToLocation)) {yield session.custom('continueToLocation', { source: focusedProcess.getSource({ path: uri }).raw, line, threadId: focusedThread.threadId });return;}const existing = _this7._model.getBreakpointAtLine(uri, line);if (existing == null) {yield _this7.addBreakpoints(uri, [{ line }]);const runToLocationBreakpoint = _this7._model.getBreakpointAtLine(uri, line);if (!(runToLocationBreakpoint != null)) {throw new Error('Invariant violation: "runToLocationBreakpoint != null"');}const removeBreakpoint = function () {_this7.removeBreakpoints(runToLocationBreakpoint.getId(), true /* skip analytics */).catch(function (error) {return (0, (_utils || _load_utils()).onUnexpectedError)(`Failed to clear run-to-location breakpoint! - ${String(error)}`);});removeBreakpointDisposable.dispose();_this7._sessionEndDisposables.remove(removeBreakpointDisposable);_this7._sessionEndDisposables.remove(removeBreakpoint);}; // Remove if the debugger stopped at any location. + const removeBreakpointDisposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(session.observeStopEvents().take(1).subscribe(removeBreakpoint)); // Remove if the session has ended without hitting it. + _this7._sessionEndDisposables.add(removeBreakpointDisposable, removeBreakpoint);}yield focusedThread.continue();})();}addWatchExpression(name) {(0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_WATCH_ADD_EXPRESSION);return this._model.addWatchExpression(name);}renameWatchExpression(id, newName) {(0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_WATCH_UPDATE_EXPRESSION);return this._model.renameWatchExpression(id, newName);}removeWatchExpressions(id) {(0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_WATCH_REMOVE_EXPRESSION);this._model.removeWatchExpressions(id);}createExpression(rawExpression) {return new (_DebuggerModel || _load_DebuggerModel()).Expression(rawExpression);}_doCreateProcess(rawConfiguration, sessionId) {var _this8 = this;return (0, _asyncToGenerator.default)(function* () {const errorHandler = function (error) {if (_this8._timer != null) {_this8._timer.onError(error);_this8._timer = null;}(0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_START_FAIL, {});const errorMessage = error instanceof Error ? error.message : error;atom.notifications.addError(`Failed to start debugger process: ${errorMessage}`);_this8._consoleDisposables.dispose();_this8._updateModeAndEmit((_constants || _load_constants()).DebuggerMode.STOPPED);if (!session.isDisconnected()) {_this8._onSessionEnd();session.disconnect().catch((_utils || _load_utils()).onUnexpectedError);}if (process != null) {_this8._model.removeProcess(process.getId());}};let process;const adapterExecutable = yield _this8._resolveAdapterExecutable(rawConfiguration);const configuration = yield (0, (_AtomServiceContainer || _load_AtomServiceContainer()).resolveDebugConfiguration)(Object.assign({}, rawConfiguration, { adapterExecutable }));(0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_START, { serviceName: configuration.adapterType, clientType: 'VSP' });const session = yield _this8._createVsDebugSession(configuration, adapterExecutable, sessionId);try {process = _this8._model.addProcess(configuration, session);_this8.focusStackFrame(null, null, process);_this8._registerSessionListeners(process, session);atom.commands.dispatch(atom.views.getView(atom.workspace), 'debugger:show');yield session.initialize({ clientID: 'atom', adapterID: configuration.adapterType, pathFormat: 'path', linesStartAt1: true, columnsStartAt1: true, supportsVariableType: true, supportsVariablePaging: false, supportsRunInTerminalRequest: (0, (_AtomServiceContainer || _load_AtomServiceContainer()).getTerminalService)() != null, locale: 'en-us' });_this8._model.setExceptionBreakpoints(session.getCapabilities().exceptionBreakpointFilters || []); // We're not awaiting launch/attach to finish because some debug adapters + // need to do custom work for launch/attach to work (e.g. mobilejs) + _this8._launchOrAttachTarget(session, configuration).catch(errorHandler);return process;} catch (error) {errorHandler(error);return null;}})();}_resolveAdapterExecutable(configuration) {return (0, _asyncToGenerator.default)(function* () {if (configuration.adapterExecutable != null) {return configuration.adapterExecutable;}return (0, (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).getVSCodeDebuggerAdapterServiceByNuclideUri)(configuration.targetUri).getAdapterExecutableInfo(configuration.adapterType);})();}_createVsDebugSession(configuration, adapterExecutable, sessionId) {var _this9 = this;return (0, _asyncToGenerator.default)(function* () {const { targetUri } = configuration;const service = (0, (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).getVSCodeDebuggerAdapterServiceByNuclideUri)(targetUri);const spawner = new service.VsRawAdapterSpawnerService();const clientPreprocessors = [];const adapterPreprocessors = [];if (configuration.clientPreprocessor != null) {clientPreprocessors.push(configuration.clientPreprocessor);}if (configuration.adapterPreprocessor != null) {adapterPreprocessors.push(configuration.adapterPreprocessor);}const isRemote = (_nuclideUri || _load_nuclideUri()).default.isRemote(targetUri);if (isRemote) {clientPreprocessors.push((0, (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).remoteToLocalProcessor)());adapterPreprocessors.push((0, (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).localToRemoteProcessor)(targetUri));}return new (_nuclideDebuggerCommon || _load_nuclideDebuggerCommon()).VsDebugSession(sessionId, (_logger || _load_logger()).default, adapterExecutable, { adapter: configuration.adapterType, host: 'debugService', isRemote }, spawner, clientPreprocessors, adapterPreprocessors, _this9._runInTerminal);})();}_launchOrAttachTarget(session, configuration) {var _this10 = this;return (0, _asyncToGenerator.default)(function* () {if (configuration.debugMode === 'attach') {yield session.attach(configuration.config);} else {// It's 'launch' + yield session.launch(configuration.config);}if (!session.isDisconnected()) {_this10._updateModeAndEmit((_constants || _load_constants()).DebuggerMode.RUNNING);}})();}_sourceIsNotAvailable(uri) {this._model.sourceIsNotAvailable(uri);}restartProcess() {var _this11 = this;return (0, _asyncToGenerator.default)(function* () {const process = _this11._getCurrentProcess();if (process == null) {return;}if (process.session.capabilities.supportsRestartRequest) {yield process.session.custom('restart', null);}yield process.session.disconnect(true);yield (0, (_promise || _load_promise()).sleep)(300);yield _this11.startDebugging(process.configuration);})();} /** + * Starts debugging. If the configOrName is not passed uses the selected configuration in the debug dropdown. + * Also saves all files, manages if compounds are present in the configuration + * and resolveds configurations via DebugConfigurationProviders. + */startDebugging(config) {var _this12 = this;return (0, _asyncToGenerator.default)(function* () {_this12._timer = (0, (_analytics || _load_analytics()).startTracking)('debugger-atom:startDebugging');if (_this12._viewModel.focusedProcess != null) {// We currently support only running only one debug session at a time. + (0, (_utils || _load_utils()).notifyOpenDebugSession)();return;}_this12._updateModeAndEmit((_constants || _load_constants()).DebuggerMode.STARTING); // Open the console window if it's not already opened. + // eslint-disable-next-line rulesdir/atom-apis + atom.workspace.open(CONSOLE_VIEW_URI, { searchAllPanes: true });_this12._consoleDisposables = _this12._registerConsoleExecutor();yield _this12._doCreateProcess(config, (_uuid || _load_uuid()).default.v4());})();}getModel() {return this._model;}_sendAllBreakpoints() {var _this13 = this;return (0, _asyncToGenerator.default)(function* () {yield Promise.all((0, (_collection || _load_collection()).distinct)(_this13._model.getBreakpoints(), function (bp) {return bp.uri;}).map(function (bp) {return _this13._sendBreakpoints(bp.uri, false);}));yield _this13._sendFunctionBreakpoints(); // send exception breakpoints at the end since some debug adapters rely on the order + yield _this13._sendExceptionBreakpoints();})();}_sendBreakpoints(uri, sourceModified = false) {var _this14 = this;return (0, _asyncToGenerator.default)(function* () {const process = _this14._getCurrentProcess();const session = _this14._getCurrentSession();if (process == null || session == null || !session.isReadyForBreakpoints()) {return;}const breakpointsToSend = _this14._model.getBreakpoints(). + filter( + function (bp) {return ( + _this14._model.areBreakpointsActivated() && bp.enabled && bp.uri === uri);}); + + + const rawSource = process.getSource({ + path: uri, + name: (_nuclideUri || _load_nuclideUri()).default.basename(uri) }). + raw; + + if (breakpointsToSend.length && !rawSource.adapterData) { + rawSource.adapterData = breakpointsToSend[0].adapterData; + } + + // The UI is 0-based, while VSP is 1-based. + const response = yield session.setBreakpoints({ + source: rawSource, + lines: breakpointsToSend.map(function (bp) {return bp.line;}), + breakpoints: breakpointsToSend.map(function (bp) {return { + line: bp.line, + column: bp.column, + condition: bp.condition, + hitCondition: bp.hitCondition };}), + + sourceModified }); + + if (response == null || response.body == null) { + return; + } + + const data = {}; + for (let i = 0; i < breakpointsToSend.length; i++) { + data[breakpointsToSend[i].getId()] = response.body.breakpoints[i]; + if (!breakpointsToSend[i].column) { + // If there was no column sent ignore the breakpoint column response from the adapter + data[breakpointsToSend[i].getId()].column = undefined; + } } - } - this._model.updateBreakpoints(data); + _this14._model.updateBreakpoints(data);})(); } - _getCurrentSession(): ?VsDebugSession { - return this._viewModel.focusedProcess == null - ? null - : (this._viewModel.focusedProcess.session: any); + _getCurrentSession() { + return this._viewModel.focusedProcess == null ? + null : + this._viewModel.focusedProcess.session; } - _getCurrentProcess(): ?IProcess { + _getCurrentProcess() { return this._viewModel.focusedProcess; } - async _sendFunctionBreakpoints(): Promise { - const session = this._getCurrentSession(); - if ( + _sendFunctionBreakpoints() {var _this15 = this;return (0, _asyncToGenerator.default)(function* () { + const session = _this15._getCurrentSession(); + if ( session == null || !session.isReadyForBreakpoints() || - !session.getCapabilities().supportsFunctionBreakpoints - ) { - return; - } + !session.getCapabilities().supportsFunctionBreakpoints) + { + return; + } - const breakpointsToSend: any = this._model - .getFunctionBreakpoints() - .filter(fbp => fbp.enabled && this._model.areBreakpointsActivated()); - const response: DebugProtocol.SetFunctionBreakpointsResponse = await session.setFunctionBreakpoints( + const breakpointsToSend = _this15._model. + getFunctionBreakpoints(). + filter(function (fbp) {return fbp.enabled && _this15._model.areBreakpointsActivated();}); + const response = yield session.setFunctionBreakpoints( { - breakpoints: breakpointsToSend, - }, - ); - if (response == null || response.body == null) { - return; - } + breakpoints: breakpointsToSend }); - const data = {}; - for (let i = 0; i < breakpointsToSend.length; i++) { - data[breakpointsToSend[i].getId()] = response.body.breakpoints[i]; - } - this._model.updateFunctionBreakpoints(data); + if (response == null || response.body == null) { + return; + } + + const data = {}; + for (let i = 0; i < breakpointsToSend.length; i++) { + data[breakpointsToSend[i].getId()] = response.body.breakpoints[i]; + } + + _this15._model.updateFunctionBreakpoints(data);})(); } - async _sendExceptionBreakpoints(): Promise { - const session = this._getCurrentSession(); - if ( + _sendExceptionBreakpoints() {var _this16 = this;return (0, _asyncToGenerator.default)(function* () { + const session = _this16._getCurrentSession(); + if ( session == null || !session.isReadyForBreakpoints() || - this._model.getExceptionBreakpoints().length === 0 - ) { - return; - } + _this16._model.getExceptionBreakpoints().length === 0) + { + return; + } + + const enabledExceptionBps = _this16._model. + getExceptionBreakpoints(). + filter(function (exb) {return exb.enabled;}); + yield session.setExceptionBreakpoints({ + filters: enabledExceptionBps.map(function (exb) {return exb.filter;}) });})(); - const enabledExceptionBps = this._model - .getExceptionBreakpoints() - .filter(exb => exb.enabled); - await session.setExceptionBreakpoints({ - filters: enabledExceptionBps.map(exb => exb.filter), - }); } - _registerConsoleExecutor(): IDisposable { - const disposables = new UniversalDisposable(); - const registerExecutor = getConsoleRegisterExecutor(); + _registerConsoleExecutor() { + const disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + const registerExecutor = (0, (_AtomServiceContainer || _load_AtomServiceContainer()).getConsoleRegisterExecutor)(); if (registerExecutor == null) { return disposables; } - const output: Subject< - ConsoleMessage | {result?: EvaluationResult}, - > = new Subject(); + const output = + + new _rxjsBundlesRxMinJs.Subject(); const evaluateExpression = rawExpression => { - const expression = new Expression(rawExpression); - const {focusedProcess, focusedStackFrame} = this._viewModel; + const expression = new (_DebuggerModel || _load_DebuggerModel()).Expression(rawExpression); + const { focusedProcess, focusedStackFrame } = this._viewModel; if (focusedProcess == null) { - logger.error('Cannot evaluate while there is no active debug session'); + (_logger || _load_logger()).default.error('Cannot evaluate while there is no active debug session'); return; } disposables.add( - // We filter here because the first value in the BehaviorSubject is null no matter what, and - // we want the console to unsubscribe the stream after the first non-null value. - expressionAsEvaluationResultStream( - expression, - focusedProcess, - focusedStackFrame, - 'repl', - ) - .skip(1) // Skip the first pending null value. - .subscribe(result => { - // Evaluate all watch expressions and fetch variables again since repl evaluation might have changed some. - this.focusStackFrame( - this._viewModel.focusedStackFrame, - this._viewModel.focusedThread, - null, - false, - ); - - if (result == null || !expression.available) { - const message: ConsoleMessage = { - text: expression.getValue(), - level: 'error', - }; - output.next(message); - } else { - output.next({data: result}); - } - }), - ); + // We filter here because the first value in the BehaviorSubject is null no matter what, and + // we want the console to unsubscribe the stream after the first non-null value. + (0, (_utils || _load_utils()).expressionAsEvaluationResultStream)( + expression, + focusedProcess, + focusedStackFrame, + 'repl'). + + skip(1) // Skip the first pending null value. + .subscribe(result => { + // Evaluate all watch expressions and fetch variables again since repl evaluation might have changed some. + this.focusStackFrame( + this._viewModel.focusedStackFrame, + this._viewModel.focusedThread, + null, + false); + + + if (result == null || !expression.available) { + const message = { + text: expression.getValue(), + level: 'error' }; + + output.next(message); + } else { + output.next({ data: result }); + } + })); + }; disposables.add( - registerExecutor({ - id: 'debugger', - name: 'Debugger', - scopeName: 'text.plain', - send(expression: string) { - evaluateExpression(expression); - }, - output, - getProperties: (fetchChildrenForLazyComponent: any), - }), - ); + registerExecutor({ + id: 'debugger', + name: 'Debugger', + scopeName: 'text.plain', + send(expression) { + evaluateExpression(expression); + }, + output, + getProperties: (_utils || _load_utils()).fetchChildrenForLazyComponent })); + + return disposables; } - dispose(): void { + dispose() { this._disposables.dispose(); this._consoleDisposables.dispose(); this._sessionEndDisposables.dispose(); - } -} + }}exports.default = DebugService; -class DebugSourceTextBufffer extends TextBuffer { - _uri: string; - constructor(contents: string, uri: string) { +class DebugSourceTextBufffer extends _atom.TextBuffer { + + + constructor(contents, uri) { super(contents); this._uri = uri; } @@ -1651,5 +1651,4 @@ class DebugSourceTextBufffer extends TextBuffer { isModified() { return false; - } -} + }} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/vsp/DebuggerModel.js b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/vsp/DebuggerModel.js index abab3d40..4326b55e 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/vsp/DebuggerModel.js +++ b/modules/atom-ide-ui/pkg/atom-ide-debugger/lib/vsp/DebuggerModel.js @@ -1,178 +1,178 @@ -/** - * 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 - * @format - */ - -/** -The following debug model implementation was ported from VSCode's debugger implementation -in https://github.com/Microsoft/vscode/tree/master/src/vs/workbench/parts/debug - -MIT License - -Copyright (c) 2015 - present Microsoft Corporation - -All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -import type { - IExpression, - IExpressionContainer, - IEvaluatableExpression, - IStackFrame, - IBreakpoint, - IRawModelUpdate, - IRawStopppedUpdate, - IRawThreadUpdate, - ISession, - IThread, - IModel, - IScope, - ISource, - IProcess, - IRawStoppedDetails, - IEnableable, - IBreakpointsChangeEvent, - IRawBreakpoint, - IExceptionInfo, - IExceptionBreakpoint, - IFunctionBreakpoint, - ITreeElement, - IVariable, - SourcePresentationHint, -} from '../types'; -import type {IProcessConfig} from 'nuclide-debugger-common'; -import * as DebugProtocol from 'vscode-debugprotocol'; - -import {Observable} from 'rxjs'; -import uuid from 'uuid'; -import nullthrows from 'nullthrows'; -import invariant from 'assert'; -import {Emitter, Range} from 'atom'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {track} from 'nuclide-commons/analytics'; -import {AnalyticsEvents, UNKNOWN_SOURCE, DEBUG_SOURCES_URI} from '../constants'; -import {openSourceLocation, onUnexpectedError} from '../utils'; -import {distinct} from 'nuclide-commons/collection'; - -export class Source implements ISource { - +uri: string; - available: boolean; - _raw: DebugProtocol.Source; - - constructor(raw: ?DebugProtocol.Source, sessionId: string) { - if (raw == null) { - this._raw = {name: UNKNOWN_SOURCE}; - } else { - this._raw = raw; - } - this.available = this._raw.name !== UNKNOWN_SOURCE; - if (this._raw.sourceReference != null && this._raw.sourceReference > 0) { - this.uri = `${DEBUG_SOURCES_URI}/${sessionId}/${ - this._raw.sourceReference - }/${this._raw.name == null ? UNKNOWN_SOURCE : this._raw.name}`; - } else { - this.uri = this._raw.path || ''; - } - } +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.Model = exports.ExceptionBreakpoint = exports.FunctionBreakpoint = exports.Breakpoint = exports.Process = exports.Thread = exports.StackFrame = exports.Scope = exports.Variable = exports.Expression = exports.Source = undefined;var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _vscodeDebugprotocol; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - get name(): ?string { - return this._raw.name; - } - get origin(): ?string { - return this._raw.origin; - } - get presentationHint(): ?SourcePresentationHint { - return this._raw.presentationHint; - } - get raw(): DebugProtocol.Source { - return this._raw; - } - get reference(): ?number { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +function _load_vscodeDebugprotocol() {return _vscodeDebugprotocol = _interopRequireWildcard(require('vscode-debugprotocol'));} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _uuid; +function _load_uuid() {return _uuid = _interopRequireDefault(require('uuid'));}var _nullthrows; +function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));} + +var _atom = require('atom');var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _analytics; +function _load_analytics() {return _analytics = require('nuclide-commons/analytics');}var _constants; +function _load_constants() {return _constants = require('../constants');}var _utils; +function _load_utils() {return _utils = require('../utils');}var _collection; +function _load_collection() {return _collection = require('nuclide-commons/collection');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */ /** + The following debug model implementation was ported from VSCode's debugger implementation + in https://github.com/Microsoft/vscode/tree/master/src/vs/workbench/parts/debug + + MIT License + + Copyright (c) 2015 - present Microsoft Corporation + + All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */class Source {constructor(raw, sessionId) {if (raw == null) {this._raw = { name: (_constants || _load_constants()).UNKNOWN_SOURCE };} else {this._raw = raw;}this.available = this._raw.name !== (_constants || _load_constants()).UNKNOWN_SOURCE;if (this._raw.sourceReference != null && this._raw.sourceReference > 0) {this.uri = `${(_constants || _load_constants()).DEBUG_SOURCES_URI}/${sessionId}/${this._raw.sourceReference}/${this._raw.name == null ? (_constants || _load_constants()).UNKNOWN_SOURCE : this._raw.name}`;} else {this.uri = this._raw.path || '';}}get name() {return this._raw.name;}get origin() {return this._raw.origin;}get presentationHint() {return this._raw.presentationHint;}get raw() {return this._raw;} + + get reference() { return this._raw.sourceReference; } - get inMemory(): boolean { - return this.uri.startsWith(DEBUG_SOURCES_URI); + get inMemory() { + return this.uri.startsWith((_constants || _load_constants()).DEBUG_SOURCES_URI); } - openInEditor(): Promise { + openInEditor() { // eslint-disable-next-line rulesdir/atom-apis return atom.workspace.open(this.uri, { searchAllPanes: true, - pending: true, - }); - } -} + pending: true }); + + }}exports.Source = Source; + + +class ExpressionContainer { + + + + + + + + + + -class ExpressionContainer implements IExpressionContainer { - static allValues: Map = new Map(); - // Use chunks to support variable paging #9537 - static BASE_CHUNK_SIZE = 100; - _value: string; - _children: ?Promise; - process: ?IProcess; - _reference: number; - _id: string; - _namedVariables: number; - _indexedVariables: number; - _startOfVariables: number; constructor( - process: ?IProcess, - reference: number, - id: string, - namedVariables: ?number, - indexedVariables: ?number, - startOfVariables: ?number, - ) { + process, + reference, + id, + namedVariables, + indexedVariables, + startOfVariables) + { this.process = process; this._reference = reference; this._id = id; this._namedVariables = namedVariables || 0; this._indexedVariables = indexedVariables || 0; this._startOfVariables = startOfVariables || 0; - } + } // Use chunks to support variable paging #9537 - get reference(): number { + get reference() { return this._reference; } - set reference(value: number) { + set reference(value) { this._reference = value; this._children = null; } - getChildren(): Promise { + getChildren() { if (this._children == null) { this._children = this._doGetChildren(); } @@ -180,107 +180,107 @@ class ExpressionContainer implements IExpressionContainer { return this._children; } - async _doGetChildren(): Promise { - if (!this.hasChildren()) { - return []; - } + _doGetChildren() {var _this = this;return (0, _asyncToGenerator.default)(function* () { + if (!_this.hasChildren()) { + return []; + } - if (!this.getChildrenInChunks) { - const variables = await this._fetchVariables(); - return variables; - } + if (!_this.getChildrenInChunks) { + const variables = yield _this._fetchVariables(); + return variables; + } - // Check if object has named variables, fetch them independent from indexed variables #9670 - let childrenArray: Array = []; - if (Boolean(this._namedVariables)) { - childrenArray = await this._fetchVariables(undefined, undefined, 'named'); - } + // Check if object has named variables, fetch them independent from indexed variables #9670 + let childrenArray = []; + if (Boolean(_this._namedVariables)) { + childrenArray = yield _this._fetchVariables(undefined, undefined, 'named'); + } - // Use a dynamic chunk size based on the number of elements #9774 - let chunkSize = ExpressionContainer.BASE_CHUNK_SIZE; - while ( - this._indexedVariables > - chunkSize * ExpressionContainer.BASE_CHUNK_SIZE - ) { - chunkSize *= ExpressionContainer.BASE_CHUNK_SIZE; - } + // Use a dynamic chunk size based on the number of elements #9774 + let chunkSize = ExpressionContainer.BASE_CHUNK_SIZE; + while ( + _this._indexedVariables > + chunkSize * ExpressionContainer.BASE_CHUNK_SIZE) + { + chunkSize *= ExpressionContainer.BASE_CHUNK_SIZE; + } - if (this._indexedVariables > chunkSize) { - // There are a lot of children, create fake intermediate values that represent chunks #9537 - const numberOfChunks = Math.ceil(this._indexedVariables / chunkSize); - for (let i = 0; i < numberOfChunks; i++) { - const start = this._startOfVariables + i * chunkSize; - const count = Math.min( + if (_this._indexedVariables > chunkSize) { + // There are a lot of children, create fake intermediate values that represent chunks #9537 + const numberOfChunks = Math.ceil(_this._indexedVariables / chunkSize); + for (let i = 0; i < numberOfChunks; i++) { + const start = _this._startOfVariables + i * chunkSize; + const count = Math.min( chunkSize, - this._indexedVariables - i * chunkSize, - ); - childrenArray.push( + _this._indexedVariables - i * chunkSize); + + childrenArray.push( new Variable( - this.process, - this, - this.reference, - `[${start}..${start + count - 1}]`, - '', - '', - null, - count, - {kind: 'virtual'}, - null, - true, - start, - ), - ); + _this.process, _this, + + _this.reference, + `[${start}..${start + count - 1}]`, + '', + '', + null, + count, + { kind: 'virtual' }, + null, + true, + start)); + + + } + + return childrenArray; } - return childrenArray; - } + const variables = yield _this._fetchVariables( + _this._startOfVariables, + _this._indexedVariables, + 'indexed'); - const variables = await this._fetchVariables( - this._startOfVariables, - this._indexedVariables, - 'indexed', - ); - return childrenArray.concat(variables); + return childrenArray.concat(variables);})(); } - getId(): string { + getId() { return this._id; } - getValue(): string { + getValue() { return this._value; } - hasChildren(): boolean { + hasChildren() { // only variables with reference > 0 have children. return this.reference > 0; } - async _fetchVariables( - start?: number, - count?: number, - filter?: 'indexed' | 'named', - ): Promise { - const process = this.process; - invariant(process); - try { - const response: DebugProtocol.VariablesResponse = await process.session.variables( + _fetchVariables( + start, + count, + filter) + {var _this2 = this;return (0, _asyncToGenerator.default)(function* () { + const process = _this2.process;if (! + process) {throw new Error('Invariant violation: "process"');} + try { + const response = yield process.session.variables( { - variablesReference: this.reference, + variablesReference: _this2.reference, start, count, - filter, - }, - ); - const variables = distinct( - response.body.variables.filter(v => v != null && v.name), - v => v.name, - ); - return variables.map( - v => - new Variable( - this.process, - this, + filter }); + + + const variables = (0, (_collection || _load_collection()).distinct)( + response.body.variables.filter(function (v) {return v != null && v.name;}), + function (v) {return v.name;}); + + return variables.map( + function (v) {return ( + new Variable( + _this2.process, _this2, + v.variablesReference, v.name, v.evaluateName, @@ -288,52 +288,52 @@ class ExpressionContainer implements IExpressionContainer { v.namedVariables, v.indexedVariables, v.presentationHint, - v.type, - ), - ); - } catch (e) { - return [ + v.type));}); + + + } catch (e) { + return [ new Variable( - this.process, - this, - 0, - null, - e.message, - '', - 0, - 0, - {kind: 'virtual'}, - null, - false, - ), - ]; - } + _this2.process, _this2, + + 0, + null, + e.message, + '', + 0, + 0, + { kind: 'virtual' }, + null, + false)]; + + + }})(); } // The adapter explicitly sents the children count of an expression only if there are lots of children which should be chunked. - get getChildrenInChunks(): boolean { + get getChildrenInChunks() { return Boolean(this._indexedVariables); } - setValue(value: string) { + setValue(value) { this._value = value; ExpressionContainer.allValues.set(this.getId(), value); } - toString(): string { + toString() { return this._value; - } -} + }}ExpressionContainer.allValues = new Map();ExpressionContainer.BASE_CHUNK_SIZE = 100; + + +class Expression extends ExpressionContainer +{ + -export class Expression extends ExpressionContainer - implements IEvaluatableExpression { - static DEFAULT_VALUE = 'not available'; - available: boolean; - _type: ?string; - name: string; - constructor(name: string, id?: string = uuid.v4()) { + + + constructor(name, id = (_uuid || _load_uuid()).default.v4()) { super(null, 0, id); this.name = name; this.available = false; @@ -345,88 +345,88 @@ export class Expression extends ExpressionContainer } } - get type(): ?string { + get type() { return this._type; } - async evaluate( - process: ?IProcess, - stackFrame: ?IStackFrame, - context: string, - ): Promise { - if (process == null || (stackFrame == null && context !== 'repl')) { - this._value = - context === 'repl' - ? 'Please start a debug session to evaluate' - : Expression.DEFAULT_VALUE; - this.available = false; - this.reference = 0; - return; - } + evaluate( + process, + stackFrame, + context) + {var _this3 = this;return (0, _asyncToGenerator.default)(function* () { + if (process == null || stackFrame == null && context !== 'repl') { + _this3._value = + context === 'repl' ? + 'Please start a debug session to evaluate' : + Expression.DEFAULT_VALUE; + _this3.available = false; + _this3.reference = 0; + return; + } - this.process = process; - try { - const response: DebugProtocol.EvaluateResponse = await process.session.evaluate( + _this3.process = process; + try { + const response = yield process.session.evaluate( { - expression: this.name, + expression: _this3.name, frameId: stackFrame ? stackFrame.frameId : undefined, - context, - }, - ); - - this.available = response != null && response.body != null; - if (response && response.body) { - this._value = response.body.result; - this.reference = response.body.variablesReference || 0; - this._namedVariables = response.body.namedVariables || 0; - this._indexedVariables = response.body.indexedVariables || 0; - this._type = response.body.type; - } - } catch (err) { - this._value = err.message; - this.available = false; - this.reference = 0; - } + context }); + + + + _this3.available = response != null && response.body != null; + if (response && response.body) { + _this3._value = response.body.result; + _this3.reference = response.body.variablesReference || 0; + _this3._namedVariables = response.body.namedVariables || 0; + _this3._indexedVariables = response.body.indexedVariables || 0; + _this3._type = response.body.type; + } + } catch (err) { + _this3._value = err.message; + _this3.available = false; + _this3.reference = 0; + }})(); } - toString(): string { + toString() { return `${this.name}\n${this._value}`; - } -} + }}exports.Expression = Expression;Expression.DEFAULT_VALUE = 'not available'; + + +class Variable extends ExpressionContainer { + + + + + + + -export class Variable extends ExpressionContainer implements IExpression { - // Used to show the error message coming from the adapter when setting the value #7807 - errorMessage: ?string; - parent: ExpressionContainer; - name: string; - evaluateName: ?string; - presentationHint: ?DebugProtocol.VariablePresentationHint; - _type: ?string; - available: boolean; constructor( - process: ?IProcess, - parent: ExpressionContainer, - reference: number, - name: ?string, - evaluateName: ?string, - value: string, - namedVariables: ?number, - indexedVariables: ?number, - presentationHint: ?DebugProtocol.VariablePresentationHint, - type: ?string, - available?: boolean = true, - _startOfVariables: ?number, - ) { + process, + parent, + reference, + name, + evaluateName, + value, + namedVariables, + indexedVariables, + presentationHint, + type, + available = true, + _startOfVariables) + { super( - process, - reference, - // flowlint-next-line sketchy-null-string:off - `variable:${parent.getId()}:${name || 'no_name'}`, - namedVariables, - indexedVariables, - _startOfVariables, - ); + process, + reference, + // flowlint-next-line sketchy-null-string:off + `variable:${parent.getId()}:${name || 'no_name'}`, + namedVariables, + indexedVariables, + _startOfVariables); + this.parent = parent; this.name = name == null ? 'no_name' : name; this.evaluateName = evaluateName; @@ -434,88 +434,88 @@ export class Variable extends ExpressionContainer implements IExpression { this._type = type; this.available = available; this._value = value; - } + } // Used to show the error message coming from the adapter when setting the value #7807 - get type(): ?string { + get type() { return this._type; } - async setVariable(value: string): Promise { - const process = nullthrows(this.process); - track(AnalyticsEvents.DEBUGGER_EDIT_VARIABLE, { - language: process.configuration.adapterType, - }); - try { - const response = await process.session.setVariable({ - name: nullthrows(this.name), - value, - variablesReference: this.parent.reference, - }); - if (response && response.body) { - this._value = response.body.value; - this._type = - response.body.type == null ? this._type : response.body.type; - this.reference = response.body.variablesReference || 0; - this._namedVariables = response.body.namedVariables || 0; - this._indexedVariables = response.body.indexedVariables || 0; - } - } catch (err) { - this.errorMessage = err.message; - } + setVariable(value) {var _this4 = this;return (0, _asyncToGenerator.default)(function* () { + const process = (0, (_nullthrows || _load_nullthrows()).default)(_this4.process); + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_EDIT_VARIABLE, { + language: process.configuration.adapterType }); + + try { + const response = yield process.session.setVariable({ + name: (0, (_nullthrows || _load_nullthrows()).default)(_this4.name), + value, + variablesReference: _this4.parent.reference }); + + if (response && response.body) { + _this4._value = response.body.value; + _this4._type = + response.body.type == null ? _this4._type : response.body.type; + _this4.reference = response.body.variablesReference || 0; + _this4._namedVariables = response.body.namedVariables || 0; + _this4._indexedVariables = response.body.indexedVariables || 0; + } + } catch (err) { + _this4.errorMessage = err.message; + }})(); } - toString(): string { + toString() { return `${this.name}: ${this._value}`; - } -} + }}exports.Variable = Variable; + + +class Scope extends ExpressionContainer { + + -export class Scope extends ExpressionContainer implements IScope { - +name: string; - +expensive: boolean; - +range: ?atom$Range; constructor( - stackFrame: IStackFrame, - index: number, - name: string, - reference: number, - expensive: boolean, - namedVariables: ?number, - indexedVariables: ?number, - range: ?atom$Range, - ) { + stackFrame, + index, + name, + reference, + expensive, + namedVariables, + indexedVariables, + range) + { super( - stackFrame.thread.process, - reference, - `scope:${stackFrame.getId()}:${name}:${index}`, - namedVariables, - indexedVariables, - ); + stackFrame.thread.process, + reference, + `scope:${stackFrame.getId()}:${name}:${index}`, + namedVariables, + indexedVariables); + this.name = name; this.expensive = expensive; this.range = range; - } -} + }}exports.Scope = Scope; + + +class StackFrame { + + + + + + + -export class StackFrame implements IStackFrame { - scopes: ?Promise; - thread: IThread; - frameId: number; - source: ISource; - name: string; - presentationHint: ?string; - range: atom$Range; - index: number; constructor( - thread: IThread, - frameId: number, - source: ISource, - name: string, - presentationHint: ?string, - range: atom$Range, - index: number, - ) { + thread, + frameId, + source, + name, + presentationHint, + range, + index) + { this.thread = thread; this.frameId = frameId; this.source = source; @@ -526,103 +526,103 @@ export class StackFrame implements IStackFrame { this.scopes = null; } - getId(): string { + getId() { return `stackframe:${this.thread.getId()}:${this.frameId}:${this.index}`; } - async getScopes(): Promise { - if (this.scopes == null) { - this.scopes = this._getScopesImpl(); - } - return (this.scopes: any); + getScopes() {var _this5 = this;return (0, _asyncToGenerator.default)(function* () { + if (_this5.scopes == null) { + _this5.scopes = _this5._getScopesImpl(); + } + return _this5.scopes;})(); } - async _getScopesImpl(): Promise { - try { - const { - body: {scopes}, - } = await this.thread.process.session.scopes({ - frameId: this.frameId, - }); - return scopes.map( - (rs, index) => - new Scope( - this, + _getScopesImpl() {var _this6 = this;return (0, _asyncToGenerator.default)(function* () { + try { + const { + body: { scopes } } = + yield _this6.thread.process.session.scopes({ + frameId: _this6.frameId }); + + return scopes.map( + function (rs, index) {return ( + new Scope(_this6, + index, rs.name, rs.variablesReference, rs.expensive, rs.namedVariables, rs.indexedVariables, - rs.line != null - ? new Range( - [rs.line - 1, (rs.column != null ? rs.column : 1) - 1], - [ - (rs.endLine != null ? rs.endLine : rs.line) - 1, - (rs.endColumn != null ? rs.endColumn : 1) - 1, - ], - ) - : null, - ), - ); - } catch (err) { - return []; - } + rs.line != null ? + new _atom.Range( + [rs.line - 1, (rs.column != null ? rs.column : 1) - 1], + [ + (rs.endLine != null ? rs.endLine : rs.line) - 1, + (rs.endColumn != null ? rs.endColumn : 1) - 1]) : + + + null));}); + + + } catch (err) { + return []; + }})(); } - async getMostSpecificScopes(range: atom$Range): Promise { - const scopes: Array = (await this.getScopes()).filter( - s => !s.expensive, - ); - const haveRangeInfo = scopes.some(s => s.range != null); - if (!haveRangeInfo) { - return scopes; - } + getMostSpecificScopes(range) {var _this7 = this;return (0, _asyncToGenerator.default)(function* () { + const scopes = (yield _this7.getScopes()).filter( + function (s) {return !s.expensive;}); + + const haveRangeInfo = scopes.some(function (s) {return s.range != null;}); + if (!haveRangeInfo) { + return scopes; + } - const scopesContainingRange = scopes - .filter(scope => scope.range != null && scope.range.containsRange(range)) - .sort((first, second) => { - const firstRange = nullthrows(first.range); - const secondRange = nullthrows(second.range); + const scopesContainingRange = scopes. + filter(function (scope) {return scope.range != null && scope.range.containsRange(range);}). + sort(function (first, second) { + const firstRange = (0, (_nullthrows || _load_nullthrows()).default)(first.range); + const secondRange = (0, (_nullthrows || _load_nullthrows()).default)(second.range); // prettier-ignore - return (firstRange.end.row - firstRange.start.row) - - (secondRange.end.row - secondRange.end.row); + return firstRange.end.row - firstRange.start.row - ( + secondRange.end.row - secondRange.end.row); }); - return scopesContainingRange.length ? scopesContainingRange : scopes; + return scopesContainingRange.length ? scopesContainingRange : scopes;})(); } - async restart(): Promise { - await this.thread.process.session.restartFrame( - {frameId: this.frameId}, - this.thread.threadId, - ); + restart() {var _this8 = this;return (0, _asyncToGenerator.default)(function* () { + yield _this8.thread.process.session.restartFrame( + { frameId: _this8.frameId }, + _this8.thread.threadId);})(); + } - toString(): string { + toString() { return `${this.name} (${ - this.source.inMemory ? nullthrows(this.source.name) : this.source.uri + this.source.inMemory ? (0, (_nullthrows || _load_nullthrows()).default)(this.source.name) : this.source.uri }:${this.range.start.row})`; } - async openInEditor(): Promise { - if (this.source.available) { - return openSourceLocation(this.source.uri, this.range.start.row); - } else { - return null; - } - } -} + openInEditor() {var _this9 = this;return (0, _asyncToGenerator.default)(function* () { + if (_this9.source.available) { + return (0, (_utils || _load_utils()).openSourceLocation)(_this9.source.uri, _this9.range.start.row); + } else { + return null; + }})(); + }}exports.StackFrame = StackFrame; + + +class Thread { + + -export class Thread implements IThread { - _callStack: IStackFrame[]; - _staleCallStack: IStackFrame[]; - stoppedDetails: ?IRawStoppedDetails; - stopped: boolean; - +process: IProcess; - +threadId: number; - name: string; - constructor(process: IProcess, name: string, threadId: number) { + + + + + constructor(process, name, threadId) { this.process = process; this.name = name; this.threadId = threadId; @@ -632,194 +632,194 @@ export class Thread implements IThread { this.stopped = false; } - getId(): string { + getId() { return `thread:${this.process.getId()}:${this.threadId}`; } - clearCallStack(): void { + clearCallStack() { if (this._callStack.length > 0) { this._staleCallStack = this._callStack; } this._callStack = []; } - getCallStack(): IStackFrame[] { + getCallStack() { return this._callStack; } - getStaleCallStack(): IStackFrame[] { + getStaleCallStack() { return this._staleCallStack; } /** - * Queries the debug adapter for the callstack and returns a promise - * which completes once the call stack has been retrieved. - * If the thread is not stopped, it returns a promise to an empty array. - * Only fetches the first stack frame for performance reasons. Calling this method consecutive times - * gets the remainder of the call stack. - */ - async fetchCallStack(levels?: number = 20): Promise { - if (!this.stopped) { - return; - } + * Queries the debug adapter for the callstack and returns a promise + * which completes once the call stack has been retrieved. + * If the thread is not stopped, it returns a promise to an empty array. + * Only fetches the first stack frame for performance reasons. Calling this method consecutive times + * gets the remainder of the call stack. + */ + fetchCallStack(levels = 20) {var _this10 = this;return (0, _asyncToGenerator.default)(function* () { + if (!_this10.stopped) { + return; + } - const start = this._callStack.length; - const callStack = await this._getCallStackImpl(start, levels); - if (start < this._callStack.length) { - // Set the stack frames for exact position we requested. To make sure no concurrent requests create duplicate stack frames #30660 - this._callStack.splice(start, this._callStack.length - start); - } - this._callStack = this._callStack.concat(callStack || []); + const start = _this10._callStack.length; + const callStack = yield _this10._getCallStackImpl(start, levels); + if (start < _this10._callStack.length) { + // Set the stack frames for exact position we requested. To make sure no concurrent requests create duplicate stack frames #30660 + _this10._callStack.splice(start, _this10._callStack.length - start); + } + _this10._callStack = _this10._callStack.concat(callStack || []);})(); } - async _getCallStackImpl( - startFrame: number, - levels: number, - ): Promise { - try { - const response: DebugProtocol.StackTraceResponse = await this.process.session.stackTrace( + _getCallStackImpl( + startFrame, + levels) + {var _this11 = this;return (0, _asyncToGenerator.default)(function* () { + try { + const response = yield _this11.process.session.stackTrace( { - threadId: this.threadId, + threadId: _this11.threadId, startFrame, - levels, - }, - ); - if (response == null || response.body == null) { - return []; - } - if (this.stoppedDetails != null) { - this.stoppedDetails.totalFrames = response.body.totalFrames; - } + levels }); + + + if (response == null || response.body == null) { + return []; + } + if (_this11.stoppedDetails != null) { + _this11.stoppedDetails.totalFrames = response.body.totalFrames; + } + + return response.body.stackFrames.map(function (rsf, index) { + const source = _this11.process.getSource(rsf.source); - return response.body.stackFrames.map((rsf, index) => { - const source = this.process.getSource(rsf.source); + return new StackFrame(_this11, - return new StackFrame( - this, rsf.id, source, rsf.name, rsf.presentationHint, // The UI is 0-based while VSP is 1-based. - new Range( - [rsf.line - 1, (rsf.column || 1) - 1], - [ - (rsf.endLine != null ? rsf.endLine : rsf.line) - 1, - (rsf.endColumn != null ? rsf.endColumn : 1) - 1, - ], - ), - startFrame + index, - ); - }); - } catch (err) { - if (this.stoppedDetails != null) { - this.stoppedDetails.framesErrorMessage = err.message; - } + new _atom.Range( + [rsf.line - 1, (rsf.column || 1) - 1], + [ + (rsf.endLine != null ? rsf.endLine : rsf.line) - 1, + (rsf.endColumn != null ? rsf.endColumn : 1) - 1]), - return []; - } + + startFrame + index); + + }); + } catch (err) { + if (_this11.stoppedDetails != null) { + _this11.stoppedDetails.framesErrorMessage = err.message; + } + + return []; + }})(); } /** - * Returns exception info promise if the exception was thrown, otherwise null - */ - async exceptionInfo(): Promise { - const session = this.process.session; - if ( - this.stoppedDetails == null || - this.stoppedDetails.reason !== 'exception' - ) { - return null; - } - const stoppedDetails = this.stoppedDetails; - if (!session.capabilities.supportsExceptionInfoRequest) { - return { - id: null, - details: null, - description: stoppedDetails.description, - breakMode: null, - }; - } + * Returns exception info promise if the exception was thrown, otherwise null + */ + exceptionInfo() {var _this12 = this;return (0, _asyncToGenerator.default)(function* () { + const session = _this12.process.session; + if ( + _this12.stoppedDetails == null || + _this12.stoppedDetails.reason !== 'exception') + { + return null; + } + const stoppedDetails = _this12.stoppedDetails; + if (!session.capabilities.supportsExceptionInfoRequest) { + return { + id: null, + details: null, + description: stoppedDetails.description, + breakMode: null }; - const exception: DebugProtocol.ExceptionInfoResponse = await session.exceptionInfo( - {threadId: this.threadId}, - ); - if (exception == null) { - return null; - } + } - return { - id: exception.body.exceptionId, - description: exception.body.description, - breakMode: exception.body.breakMode, - details: exception.body.details, - }; - } + const exception = yield session.exceptionInfo( + { threadId: _this12.threadId }); + + if (exception == null) { + return null; + } + + return { + id: exception.body.exceptionId, + description: exception.body.description, + breakMode: exception.body.breakMode, + details: exception.body.details };})(); - async next(): Promise { - track(AnalyticsEvents.DEBUGGER_STEP_OVER); - await this.process.session.next({threadId: this.threadId}); } - async stepIn(): Promise { - track(AnalyticsEvents.DEBUGGER_STEP_INTO); - await this.process.session.stepIn({threadId: this.threadId}); + next() {var _this13 = this;return (0, _asyncToGenerator.default)(function* () { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_STEP_OVER); + yield _this13.process.session.next({ threadId: _this13.threadId });})(); } - async stepOut(): Promise { - track(AnalyticsEvents.DEBUGGER_STEP_OUT); - await this.process.session.stepOut({threadId: this.threadId}); + stepIn() {var _this14 = this;return (0, _asyncToGenerator.default)(function* () { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_STEP_INTO); + yield _this14.process.session.stepIn({ threadId: _this14.threadId });})(); } - async stepBack(): Promise { - track(AnalyticsEvents.DEBUGGER_STEP_BACK); - await this.process.session.stepBack({threadId: this.threadId}); + stepOut() {var _this15 = this;return (0, _asyncToGenerator.default)(function* () { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_STEP_OUT); + yield _this15.process.session.stepOut({ threadId: _this15.threadId });})(); } - async continue(): Promise { - track(AnalyticsEvents.DEBUGGER_STEP_CONTINUE); - await this.process.session.continue({threadId: this.threadId}); + stepBack() {var _this16 = this;return (0, _asyncToGenerator.default)(function* () { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_STEP_BACK); + yield _this16.process.session.stepBack({ threadId: _this16.threadId });})(); } - async pause(): Promise { - track(AnalyticsEvents.DEBUGGER_STEP_PAUSE); - await this.process.session.pause({threadId: this.threadId}); + continue() {var _this17 = this;return (0, _asyncToGenerator.default)(function* () { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_STEP_CONTINUE); + yield _this17.process.session.continue({ threadId: _this17.threadId });})(); } - async reverseContinue(): Promise { - await this.process.session.reverseContinue({threadId: this.threadId}); + pause() {var _this18 = this;return (0, _asyncToGenerator.default)(function* () { + (0, (_analytics || _load_analytics()).track)((_constants || _load_constants()).AnalyticsEvents.DEBUGGER_STEP_PAUSE); + yield _this18.process.session.pause({ threadId: _this18.threadId });})(); } -} -export class Process implements IProcess { - _sources: Map; - _threads: Map; - _session: ISession & ITreeElement; - _configuration: IProcessConfig; + reverseContinue() {var _this19 = this;return (0, _asyncToGenerator.default)(function* () { + yield _this19.process.session.reverseContinue({ threadId: _this19.threadId });})(); + }}exports.Thread = Thread; + - constructor(configuration: IProcessConfig, session: ISession & ITreeElement) { +class Process { + + + + + + constructor(configuration, session) { this._configuration = configuration; this._session = session; this._threads = new Map(); this._sources = new Map(); } - get sources(): Map { + get sources() { return this._sources; } - get session(): ISession & ITreeElement { + get session() { return this._session; } - get configuration(): IProcessConfig { + get configuration() { return this._configuration; } - getSource(raw: ?DebugProtocol.Source): ISource { + getSource(raw) { let source = new Source(raw, this.getId()); if (this._sources.has(source.uri)) { - source = nullthrows(this._sources.get(source.uri)); + source = (0, (_nullthrows || _load_nullthrows()).default)(this._sources.get(source.uri)); } else { this._sources.set(source.uri, source); } @@ -827,20 +827,20 @@ export class Process implements IProcess { return source; } - getThread(threadId: number): ?Thread { + getThread(threadId) { return this._threads.get(threadId); } - getAllThreads(): IThread[] { + getAllThreads() { return Array.from(this._threads.values()); } - getId(): string { + getId() { return this._session.getId(); } - rawStoppedUpdate(data: IRawStopppedUpdate): void { - const {threadId, stoppedDetails} = data; + rawStoppedUpdate(data) { + const { threadId, stoppedDetails } = data; if (threadId != null && !this._threads.has(threadId)) { // We're being asked to update a thread we haven't seen yet, so // create it @@ -853,34 +853,34 @@ export class Process implements IProcess { if (stoppedDetails.allThreadsStopped) { this._threads.forEach(thread => { thread.stoppedDetails = - thread.threadId === threadId ? stoppedDetails : thread.stoppedDetails; + thread.threadId === threadId ? stoppedDetails : thread.stoppedDetails; thread.stopped = true; thread.clearCallStack(); }); } else if (threadId != null) { // One thread is stopped, only update that thread. - const thread = nullthrows(this._threads.get(threadId)); + const thread = (0, (_nullthrows || _load_nullthrows()).default)(this._threads.get(threadId)); thread.stoppedDetails = stoppedDetails; thread.clearCallStack(); thread.stopped = true; } } - rawThreadUpdate(data: IRawThreadUpdate): void { - const {thread} = data; + rawThreadUpdate(data) { + const { thread } = data; if (!this._threads.has(thread.id)) { // A new thread came in, initialize it. this._threads.set(thread.id, new Thread(this, thread.name, thread.id)); } else if (thread.name) { // Just the thread name got updated #18244 - nullthrows(this._threads.get(thread.id)).name = thread.name; + (0, (_nullthrows || _load_nullthrows()).default)(this._threads.get(thread.id)).name = thread.name; } } - clearThreads(removeThreads: boolean, reference?: number): void { + clearThreads(removeThreads, reference) { if (reference != null) { if (this._threads.has(reference)) { - const thread = nullthrows(this._threads.get(reference)); + const thread = (0, (_nullthrows || _load_nullthrows()).default)(this._threads.get(reference)); thread.clearCallStack(); thread.stoppedDetails = null; thread.stopped = false; @@ -903,57 +903,57 @@ export class Process implements IProcess { } } - async completions( - frameId: number, - text: string, - position: atom$Point, - overwriteBefore: number, - ): Promise> { - if (!this._session.capabilities.supportsCompletionsRequest) { - return []; - } - try { - const response = await this._session.completions({ - frameId, - text, - column: position.column, - line: position.row, - }); - if (response && response.body && response.body.targets) { - return response.body.targets; - } else { + completions( + frameId, + text, + position, + overwriteBefore) + {var _this20 = this;return (0, _asyncToGenerator.default)(function* () { + if (!_this20._session.capabilities.supportsCompletionsRequest) { return []; } - } catch (error) { - return []; - } - } -} - -export class Breakpoint implements IBreakpoint { - verified: boolean; - idFromAdapter: ?number; - message: ?string; - endLine: ?number; - endColumn: ?number; - id: string; - uri: string; - line: number; - column: number; - enabled: boolean; - condition: ?string; - hitCondition: ?string; - adapterData: any; + try { + const response = yield _this20._session.completions({ + frameId, + text, + column: position.column, + line: position.row }); + + if (response && response.body && response.body.targets) { + return response.body.targets; + } else { + return []; + } + } catch (error) { + return []; + }})(); + }}exports.Process = Process; + + +class Breakpoint { + + + + + + + + + + + + + constructor( - uri: string, - line: number, - column: ?number, - enabled: ?boolean, - condition: ?string, - hitCondition: ?string, - adapterData?: any, - ) { + uri, + line, + column, + enabled, + condition, + hitCondition, + adapterData) + { this.uri = uri; this.line = line; this.column = column == null ? 1 : column; @@ -962,79 +962,79 @@ export class Breakpoint implements IBreakpoint { this.hitCondition = hitCondition; this.adapterData = adapterData; this.verified = false; - this.id = uuid.v4(); + this.id = (_uuid || _load_uuid()).default.v4(); this.endLine = null; } - getId(): string { + getId() { return this.id; - } -} + }}exports.Breakpoint = Breakpoint; + + +class FunctionBreakpoint { -export class FunctionBreakpoint implements IFunctionBreakpoint { - id: string; - verified: boolean; - idFromAdapter: ?number; - name: string; - enabled: boolean; - hitCondition: ?string; - condition: ?string; - constructor(name: string, enabled: boolean, hitCondition: ?string) { + + + + + + + constructor(name, enabled, hitCondition) { this.name = name; this.enabled = enabled; this.hitCondition = hitCondition; this.condition = null; this.verified = false; this.idFromAdapter = null; - this.id = uuid.v4(); + this.id = (_uuid || _load_uuid()).default.v4(); } - getId(): string { + getId() { return this.id; - } -} + }}exports.FunctionBreakpoint = FunctionBreakpoint; + + +class ExceptionBreakpoint { -export class ExceptionBreakpoint implements IExceptionBreakpoint { - _id: string; - +filter: string; - +label: string; - enabled: boolean; - constructor(filter: string, label: string, enabled: ?boolean) { + + + + constructor(filter, label, enabled) { this.filter = filter; this.label = label; this.enabled = enabled == null ? false : enabled; - this._id = uuid.v4(); + this._id = (_uuid || _load_uuid()).default.v4(); } - getId(): string { + getId() { return this._id; - } -} + }}exports.ExceptionBreakpoint = ExceptionBreakpoint; + const BREAKPOINTS_CHANGED = 'BREAKPOINTS_CHANGED'; const CALLSTACK_CHANGED = 'CALLSTACK_CHANGED'; const WATCH_EXPRESSIONS_CHANGED = 'WATCH_EXPRESSIONS_CHANGED'; -export class Model implements IModel { - _processes: Process[]; - _schedulers: Map; - _breakpoints: Breakpoint[]; - _breakpointsActivated: boolean; - _functionBreakpoints: FunctionBreakpoint[]; - _exceptionBreakpoints: ExceptionBreakpoint[]; - _watchExpressions: Expression[]; - _disposables: UniversalDisposable; - _emitter: Emitter; +class Model { + + + + + + + + + constructor( - breakpoints: Breakpoint[], - breakpointsActivated: boolean, - functionBreakpoints: FunctionBreakpoint[], - exceptionBreakpoints: ExceptionBreakpoint[], - watchExpressions: Expression[], - ) { + breakpoints, + breakpointsActivated, + functionBreakpoints, + exceptionBreakpoints, + watchExpressions) + { this._processes = []; this._schedulers = new Map(); this._breakpoints = breakpoints; @@ -1042,65 +1042,65 @@ export class Model implements IModel { this._functionBreakpoints = functionBreakpoints; this._exceptionBreakpoints = exceptionBreakpoints; this._watchExpressions = watchExpressions; - this._emitter = new Emitter(); - this._disposables = new UniversalDisposable(this._emitter); + this._emitter = new _atom.Emitter(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(this._emitter); } - getId(): string { + getId() { return 'root'; } - getProcesses(): IProcess[] { - return (this._processes: any); + getProcesses() { + return this._processes; } addProcess( - configuration: IProcessConfig, - session: ISession & ITreeElement, - ): Process { + configuration, + session) + { const process = new Process(configuration, session); this._processes.push(process); return process; } - removeProcess(id: string): void { + removeProcess(id) { this._processes = this._processes.filter(p => p.getId() !== id); this._emitter.emit(CALLSTACK_CHANGED); } onDidChangeBreakpoints( - callback: (event: IBreakpointsChangeEvent) => mixed, - ): IDisposable { + callback) + { return this._emitter.on(BREAKPOINTS_CHANGED, callback); } - onDidChangeCallStack(callback: () => mixed): IDisposable { + onDidChangeCallStack(callback) { return this._emitter.on(CALLSTACK_CHANGED, callback); } onDidChangeWatchExpressions( - callback: (expression: ?IExpression) => mixed, - ): IDisposable { + callback) + { return this._emitter.on(WATCH_EXPRESSIONS_CHANGED, callback); } - rawUpdate(data: IRawModelUpdate): void { - const process = this._processes - .filter(p => p.getId() === data.sessionId) - .pop(); + rawUpdate(data) { + const process = this._processes. + filter(p => p.getId() === data.sessionId). + pop(); if (process == null) { return; } if (data.stoppedDetails != null) { - process.rawStoppedUpdate((data: any)); + process.rawStoppedUpdate(data); } else { - process.rawThreadUpdate((data: any)); + process.rawThreadUpdate(data); } this._emitter.emit(CALLSTACK_CHANGED); } - clearThreads(id: string, removeThreads: boolean, reference?: number): void { + clearThreads(id, removeThreads, reference) { const process = this._processes.filter(p => p.getId() === id).pop(); this._schedulers.forEach(scheduler => scheduler.unsubscribe()); this._schedulers.clear(); @@ -1111,115 +1111,115 @@ export class Model implements IModel { } } - async fetchCallStack(threadI: IThread): Promise { - const thread: Thread = (threadI: any); - if ( - nullthrows(thread.process).session.capabilities - .supportsDelayedStackTraceLoading - ) { - // For improved performance load the first stack frame and then load the rest async. - await thread.fetchCallStack(1); - if (!this._schedulers.has(thread.getId())) { - this._schedulers.set( + fetchCallStack(threadI) {var _this21 = this;return (0, _asyncToGenerator.default)(function* () { + const thread = threadI; + if ( + (0, (_nullthrows || _load_nullthrows()).default)(thread.process).session.capabilities. + supportsDelayedStackTraceLoading) + { + // For improved performance load the first stack frame and then load the rest async. + yield thread.fetchCallStack(1); + if (!_this21._schedulers.has(thread.getId())) { + _this21._schedulers.set( thread.getId(), - Observable.timer(500).subscribe(() => { - thread - .fetchCallStack(19) - .then( - () => this._emitter.emit(CALLSTACK_CHANGED), - onUnexpectedError, - ); - }), - ); + _rxjsBundlesRxMinJs.Observable.timer(500).subscribe(function () { + thread. + fetchCallStack(19). + then( + function () {return _this21._emitter.emit(CALLSTACK_CHANGED);}, (_utils || _load_utils()).onUnexpectedError); + + + })); + + } + } else { + thread.clearCallStack(); + yield thread.fetchCallStack(); } - } else { - thread.clearCallStack(); - await thread.fetchCallStack(); - } - this._emitter.emit(CALLSTACK_CHANGED); + _this21._emitter.emit(CALLSTACK_CHANGED);})(); } - getBreakpoints(): IBreakpoint[] { - return (this._breakpoints: any); + getBreakpoints() { + return this._breakpoints; } - getBreakpointAtLine(uri: string, line: number): ?IBreakpoint { + getBreakpointAtLine(uri, line) { return this._breakpoints.find(bp => bp.uri === uri && bp.line === line); } - getBreakpointById(id: string): ?IBreakpoint { + getBreakpointById(id) { return this._breakpoints.find(bp => bp.getId() === id); } - getFunctionBreakpoints(): IFunctionBreakpoint[] { - return (this._functionBreakpoints: any); + getFunctionBreakpoints() { + return this._functionBreakpoints; } - getExceptionBreakpoints(): IExceptionBreakpoint[] { - return (this._exceptionBreakpoints: any); + getExceptionBreakpoints() { + return this._exceptionBreakpoints; } setExceptionBreakpoints( - data: DebugProtocol.ExceptionBreakpointsFilter[], - ): void { + data) + { this._exceptionBreakpoints = data.map(d => { - const ebp = this._exceptionBreakpoints - .filter(bp => bp.filter === d.filter) - .pop(); + const ebp = this._exceptionBreakpoints. + filter(bp => bp.filter === d.filter). + pop(); return new ExceptionBreakpoint( - d.filter, - d.label, - ebp ? ebp.enabled : d.default, - ); + d.filter, + d.label, + ebp ? ebp.enabled : d.default); + }); this._emitter.emit(BREAKPOINTS_CHANGED); } - areBreakpointsActivated(): boolean { + areBreakpointsActivated() { return this._breakpointsActivated; } - setBreakpointsActivated(activated: boolean): void { + setBreakpointsActivated(activated) { this._breakpointsActivated = activated; this._emitter.emit(BREAKPOINTS_CHANGED); } addBreakpoints( - uri: string, - rawData: IRawBreakpoint[], - fireEvent?: boolean = true, - ): Breakpoint[] { + uri, + rawData, + fireEvent = true) + { const newBreakpoints = rawData.map( - rawBp => - new Breakpoint( - uri, - rawBp.line, - rawBp.column, - rawBp.enabled, - rawBp.condition, - rawBp.hitCondition, - ), - ); + rawBp => + new Breakpoint( + uri, + rawBp.line, + rawBp.column, + rawBp.enabled, + rawBp.condition, + rawBp.hitCondition)); + + this._breakpoints = this._breakpoints.concat(newBreakpoints); this._breakpointsActivated = true; this._sortAndDeDup(); if (fireEvent) { - this._emitter.emit(BREAKPOINTS_CHANGED, {added: newBreakpoints}); + this._emitter.emit(BREAKPOINTS_CHANGED, { added: newBreakpoints }); } return newBreakpoints; } - removeBreakpoints(toRemove: IBreakpoint[]): void { + removeBreakpoints(toRemove) { this._breakpoints = this._breakpoints.filter( - bp => !toRemove.some(r => r.getId() === bp.getId()), - ); - this._emitter.emit(BREAKPOINTS_CHANGED, {removed: toRemove}); + bp => !toRemove.some(r => r.getId() === bp.getId())); + + this._emitter.emit(BREAKPOINTS_CHANGED, { removed: toRemove }); } - updateBreakpoints(data: {[id: string]: DebugProtocol.Breakpoint}): void { - const updated: IBreakpoint[] = []; + updateBreakpoints(data) { + const updated = []; this._breakpoints.forEach(bp => { const bpData = data[bp.getId()]; if (bpData != null) { @@ -1230,17 +1230,17 @@ export class Model implements IModel { bp.verified = bpData.verified != null ? bpData.verified : bp.verified; bp.idFromAdapter = bpData.id; bp.message = bpData.message; - bp.adapterData = bpData.source - ? bpData.source.adapterData - : bp.adapterData; + bp.adapterData = bpData.source ? + bpData.source.adapterData : + bp.adapterData; updated.push(bp); } }); this._sortAndDeDup(); - this._emitter.emit(BREAKPOINTS_CHANGED, {changed: updated}); + this._emitter.emit(BREAKPOINTS_CHANGED, { changed: updated }); } - _sortAndDeDup(): void { + _sortAndDeDup() { this._breakpoints = this._breakpoints.sort((first, second) => { if (first.uri !== second.uri) { return first.uri.localeCompare(second.uri); @@ -1251,18 +1251,18 @@ export class Model implements IModel { return first.line - second.line; }); - this._breakpoints = distinct( - this._breakpoints, - bp => `${bp.uri}:${bp.line}:${bp.column}`, - ); + this._breakpoints = (0, (_collection || _load_collection()).distinct)( + this._breakpoints, + bp => `${bp.uri}:${bp.line}:${bp.column}`); + } - setEnablement(element: IEnableable, enable: boolean): void { - const changed: Array = []; + setEnablement(element, enable) { + const changed = []; if ( - element.enabled !== enable && - (element instanceof Breakpoint || element instanceof FunctionBreakpoint) - ) { + element.enabled !== enable && ( + element instanceof Breakpoint || element instanceof FunctionBreakpoint)) + { changed.push(element); } @@ -1271,11 +1271,11 @@ export class Model implements IModel { element.verified = false; } - this._emitter.emit(BREAKPOINTS_CHANGED, {changed}); + this._emitter.emit(BREAKPOINTS_CHANGED, { changed }); } - enableOrDisableAllBreakpoints(enable: boolean): void { - const changed: (IBreakpoint | IFunctionBreakpoint)[] = []; + enableOrDisableAllBreakpoints(enable) { + const changed = []; this._breakpoints.forEach(bp => { if (bp.enabled !== enable) { changed.push(bp); @@ -1292,29 +1292,29 @@ export class Model implements IModel { fbp.enabled = enable; }); - this._emitter.emit(BREAKPOINTS_CHANGED, {changed}); + this._emitter.emit(BREAKPOINTS_CHANGED, { changed }); } - addFunctionBreakpoint(functionName: string): FunctionBreakpoint { + addFunctionBreakpoint(functionName) { const newFunctionBreakpoint = new FunctionBreakpoint( - functionName, - true, - null, - ); + functionName, + true, + null); + this._functionBreakpoints.push(newFunctionBreakpoint); - this._emitter.emit(BREAKPOINTS_CHANGED, {added: [newFunctionBreakpoint]}); + this._emitter.emit(BREAKPOINTS_CHANGED, { added: [newFunctionBreakpoint] }); return newFunctionBreakpoint; } - updateFunctionBreakpoints(data: { - [id: string]: { - name?: string, - verified?: boolean, - id?: number, - hitCondition?: string, - }, - }): void { - const changed: IFunctionBreakpoint[] = []; + updateFunctionBreakpoints(data) + + + + + + + { + const changed = []; this._functionBreakpoints.forEach(fbp => { const fbpData = data[fbp.getId()]; @@ -1328,34 +1328,34 @@ export class Model implements IModel { } }); - this._emitter.emit(BREAKPOINTS_CHANGED, {changed}); + this._emitter.emit(BREAKPOINTS_CHANGED, { changed }); } - removeFunctionBreakpoints(id?: string): void { - let removed: FunctionBreakpoint[]; + removeFunctionBreakpoints(id) { + let removed; if (id != null) { removed = this._functionBreakpoints.filter(fbp => fbp.getId() === id); this._functionBreakpoints = this._functionBreakpoints.filter( - fbp => fbp.getId() !== id, - ); + fbp => fbp.getId() !== id); + } else { removed = this._functionBreakpoints; this._functionBreakpoints = []; } - this._emitter.emit(BREAKPOINTS_CHANGED, {removed}); + this._emitter.emit(BREAKPOINTS_CHANGED, { removed }); } - getWatchExpressions(): IEvaluatableExpression[] { - return (this._watchExpressions: any); + getWatchExpressions() { + return this._watchExpressions; } - addWatchExpression(name: string): void { + addWatchExpression(name) { const we = new Expression(name); this._watchExpressions.push(we); this._emitter.emit(WATCH_EXPRESSIONS_CHANGED, we); } - renameWatchExpression(id: string, newName: string): void { + renameWatchExpression(id, newName) { const filtered = this._watchExpressions.filter(we => we.getId() === id); if (filtered.length === 1) { filtered[0].name = newName; @@ -1363,22 +1363,21 @@ export class Model implements IModel { } } - removeWatchExpressions(id: ?string): void { + removeWatchExpressions(id) { this._watchExpressions = - id != null ? this._watchExpressions.filter(we => we.getId() !== id) : []; + id != null ? this._watchExpressions.filter(we => we.getId() !== id) : []; this._emitter.emit(WATCH_EXPRESSIONS_CHANGED); } - sourceIsNotAvailable(uri: string): void { + sourceIsNotAvailable(uri) { this._processes.forEach(p => { if (p.sources.has(uri)) { - nullthrows(p.sources.get(uri)).available = false; + (0, (_nullthrows || _load_nullthrows()).default)(p.sources.get(uri)).available = false; } }); this._emitter.emit(CALLSTACK_CHANGED); } - dispose(): void { + dispose() { this._disposables.dispose(); - } -} + }}exports.Model = Model; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-definitions/lib/DefinitionCache.js b/modules/atom-ide-ui/pkg/atom-ide-definitions/lib/DefinitionCache.js index 6f3a8c27..5896007b 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-definitions/lib/DefinitionCache.js +++ b/modules/atom-ide-ui/pkg/atom-ide-definitions/lib/DefinitionCache.js @@ -1,3 +1,23 @@ +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _range; + + + + + + + + + + + + +function _load_range() {return _range = require('nuclide-commons-atom/range');}var _range2; +function _load_range2() {return _range2 = require('nuclide-commons/range');}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +// An atom$Range-aware, single-item cache for the common case of requerying +// a definition (such as previewing hyperclick and then jumping to the +// destination). It invalidates whenever the originating editor changes. /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,70 +26,50 @@ * 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 + * * @format - */ - -import type {DefinitionQueryResult} from './types'; -import {wordAtPosition} from 'nuclide-commons-atom/range'; -import {isPositionInRange} from 'nuclide-commons/range'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; + */class DefinitionCache {constructor() {this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default();}dispose() {this._disposables.dispose();}get( + editor, + position, + getImpl) + {var _this = this;return (0, _asyncToGenerator.default)(function* () { + // queryRange is often a list of one range + if ( + _this._cachedResultRange != null && + _this._cachedResultEditor === editor && + (0, (_range2 || _load_range2()).isPositionInRange)(position, _this._cachedResultRange)) + { + return _this._cachedResultPromise; + } -// An atom$Range-aware, single-item cache for the common case of requerying -// a definition (such as previewing hyperclick and then jumping to the -// destination). It invalidates whenever the originating editor changes. -class DefinitionCache { - _cachedResultEditor: ?atom$TextEditor; - _cachedResultPromise: ?Promise; - _cachedResultRange: ?atom$Range; - _disposables: UniversalDisposable = new UniversalDisposable(); - - dispose() { - this._disposables.dispose(); - } - - async get( - editor: atom$TextEditor, - position: atom$Point, - getImpl: () => Promise, - ): Promise { - // queryRange is often a list of one range - if ( - this._cachedResultRange != null && - this._cachedResultEditor === editor && - isPositionInRange(position, this._cachedResultRange) - ) { - return this._cachedResultPromise; - } - - // invalidate whenever the buffer changes - const invalidateAndStopListening = () => { - this._cachedResultEditor = null; - this._cachedResultRange = null; - this._cachedResultRange = null; - this._disposables.remove(editorDisposables); - editorDisposables.dispose(); - }; - const editorDisposables = new UniversalDisposable( + // invalidate whenever the buffer changes + const invalidateAndStopListening = function () { + _this._cachedResultEditor = null; + _this._cachedResultRange = null; + _this._cachedResultRange = null; + _this._disposables.remove(editorDisposables); + editorDisposables.dispose(); + }; + const editorDisposables = new (_UniversalDisposable || _load_UniversalDisposable()).default( editor.getBuffer().onDidChangeText(invalidateAndStopListening), - editor.onDidDestroy(invalidateAndStopListening), - ); - this._disposables.add(editorDisposables); - - const wordGuess = wordAtPosition(editor, position); - this._cachedResultRange = wordGuess && wordGuess.range; - this._cachedResultEditor = editor; - this._cachedResultPromise = getImpl().then(result => { - // Rejected providers turn into null values here. - // Invalidate the cache to ensure that the user can retry the request. - if (result == null) { - invalidateAndStopListening(); - } - return result; - }); + editor.onDidDestroy(invalidateAndStopListening)); + + _this._disposables.add(editorDisposables); + + const wordGuess = (0, (_range || _load_range()).wordAtPosition)(editor, position); + _this._cachedResultRange = wordGuess && wordGuess.range; + _this._cachedResultEditor = editor; + _this._cachedResultPromise = getImpl().then(function (result) { + // Rejected providers turn into null values here. + // Invalidate the cache to ensure that the user can retry the request. + if (result == null) { + invalidateAndStopListening(); + } + return result; + }); + + return _this._cachedResultPromise;})(); + }}exports.default = - return this._cachedResultPromise; - } -} -export default DefinitionCache; +DefinitionCache; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-definitions/lib/getPreviewDatatipFromDefinitionResult.js b/modules/atom-ide-ui/pkg/atom-ide-definitions/lib/getPreviewDatatipFromDefinitionResult.js index 15977e6b..1c49be4e 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-definitions/lib/getPreviewDatatipFromDefinitionResult.js +++ b/modules/atom-ide-ui/pkg/atom-ide-definitions/lib/getPreviewDatatipFromDefinitionResult.js @@ -1,97 +1,110 @@ -/** - * 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 - * @format - */ - -import analytics from 'nuclide-commons/analytics'; -import {getDefinitionPreview as getLocalFileDefinitionPreview} from 'nuclide-commons/symbol-definition-preview'; - -import React from 'react'; -import type {Datatip} from '../../atom-ide-datatip/lib/types'; - -import type {Definition, DefinitionPreviewProvider} from './types'; - -export default (async function getPreviewDatatipFromDefinition( - range: atom$Range, - definitions: Array, - definitionPreviewProvider: ?DefinitionPreviewProvider, - grammar: atom$Grammar, -): Promise { - if (definitions.length === 1) { - const definition = definitions[0]; - // Some providers (e.g. Flow) return negative positions. - if (definition.position.row < 0) { - return null; - } +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));let getPreview = (() => {var _ref2 = (0, _asyncToGenerator.default)( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - const definitionPreview = await getPreview( - definition, - definitionPreviewProvider, - ); - if (definitionPreview == null) { - return null; - } - // if mimetype is image return image component with base-64 encoded - // image contents, otherwise use markedStrings - if (definitionPreview.mime.startsWith('image/')) { - return { - component: () => ( - - ), - range, - }; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + function* ( + definition, + definitionPreviewProvider) + { + let getDefinitionPreviewFn; + if (definitionPreviewProvider == null) { + getDefinitionPreviewFn = (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview; + } else { + getDefinitionPreviewFn = definitionPreviewProvider.getDefinitionPreview.bind( + definitionPreviewProvider); + } - return { - markedStrings: [ - { - type: 'snippet', - value: definitionPreview.contents, - grammar, - }, - ], - range, - }; - } - - return { - markedStrings: [ - { - type: 'markdown', - value: `${definitions.length} definitions found. Click to jump.`, - grammar, - }, - ], - range, - }; -}); - -async function getPreview( - definition: Definition, - definitionPreviewProvider: ?DefinitionPreviewProvider, -) { - let getDefinitionPreviewFn; - if (definitionPreviewProvider == null) { - getDefinitionPreviewFn = getLocalFileDefinitionPreview; - } else { - getDefinitionPreviewFn = definitionPreviewProvider.getDefinitionPreview.bind( - definitionPreviewProvider, - ); - } - - return analytics.trackTiming('hyperclickPreview.getDefinitionPreview', () => - getDefinitionPreviewFn(definition), - ); -} + + return (_analytics || _load_analytics()).default.trackTiming('hyperclickPreview.getDefinitionPreview', function () {return ( + getDefinitionPreviewFn(definition));}); + + });return function getPreview(_x5, _x6) {return _ref2.apply(this, arguments);};})();var _analytics;function _load_analytics() {return _analytics = _interopRequireDefault(require('nuclide-commons/analytics'));}var _symbolDefinitionPreview;function _load_symbolDefinitionPreview() {return _symbolDefinitionPreview = require('nuclide-commons/symbol-definition-preview');}var _react = _interopRequireDefault(require('react'));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}exports.default = (() => {var _ref = (0, _asyncToGenerator.default)(function* (range, definitions, definitionPreviewProvider, grammar) {if (definitions.length === 1) {const definition = definitions[0]; // Some providers (e.g. Flow) return negative positions. + if (definition.position.row < 0) {return null;}const definitionPreview = yield getPreview(definition, definitionPreviewProvider);if (definitionPreview == null) {return null;} // if mimetype is image return image component with base-64 encoded + // image contents, otherwise use markedStrings + if (definitionPreview.mime.startsWith('image/')) {return { component: function () {return _react.default.createElement('img', { src: `data:${definitionPreview.mime};${definitionPreview.encoding},${definitionPreview.contents}` });}, range };}return { markedStrings: [{ type: 'snippet', value: definitionPreview.contents, grammar }], range };}return { markedStrings: [{ type: 'markdown', value: `${definitions.length} definitions found. Click to jump.`, grammar }], range };});function getPreviewDatatipFromDefinition(_x, _x2, _x3, _x4) {return _ref.apply(this, arguments);}return getPreviewDatatipFromDefinition;})(); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-definitions/lib/main.js b/modules/atom-ide-ui/pkg/atom-ide-definitions/lib/main.js index 4c6b11a3..d7abf324 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-definitions/lib/main.js +++ b/modules/atom-ide-ui/pkg/atom-ide-definitions/lib/main.js @@ -1,248 +1,248 @@ -/** - * 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 - * @format - */ - -// This package provides Hyperclick results for any language which provides a +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _log4js; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +function _load_log4js() {return _log4js = require('log4js');} +var _atom = require('atom');var _analytics; + +function _load_analytics() {return _analytics = _interopRequireDefault(require('nuclide-commons/analytics'));}var _createPackage; +function _load_createPackage() {return _createPackage = _interopRequireDefault(require('nuclide-commons-atom/createPackage'));}var _featureConfig; +function _load_featureConfig() {return _featureConfig = _interopRequireDefault(require('nuclide-commons-atom/feature-config'));}var _range; +function _load_range() {return _range = require('nuclide-commons-atom/range');}var _nuclideUri; +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));}var _ProviderRegistry; +function _load_ProviderRegistry() {return _ProviderRegistry = _interopRequireDefault(require('nuclide-commons-atom/ProviderRegistry'));}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _goToLocation; +function _load_goToLocation() {return _goToLocation = require('nuclide-commons-atom/go-to-location');}var _DefinitionCache; + +function _load_DefinitionCache() {return _DefinitionCache = _interopRequireDefault(require('./DefinitionCache'));}var _getPreviewDatatipFromDefinitionResult; +function _load_getPreviewDatatipFromDefinitionResult() {return _getPreviewDatatipFromDefinitionResult = _interopRequireDefault(require('./getPreviewDatatipFromDefinitionResult'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */ // This package provides Hyperclick results for any language which provides a // DefinitionProvider. +class Activation {constructor() {this._providers = new (_ProviderRegistry || _load_ProviderRegistry()).default();this._definitionCache = new (_DefinitionCache || _load_DefinitionCache()).default();this._triggerKeys = new Set(); + + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default( + (_featureConfig || _load_featureConfig()).default.observe( + getPlatformKeys(process.platform), + newValue => { + this._triggerKeys = new Set( + // flowlint-next-line sketchy-null-string:off + newValue ? newValue.split(',') : null); + + })); + -import type { - HyperclickProvider, - HyperclickSuggestion, -} from '../../hyperclick/lib/types'; - -import type { - Datatip, - DatatipService, - ModifierDatatipProvider, - ModifierKey, -} from '../../atom-ide-datatip/lib/types'; - -import type { - DefinitionQueryResult, - DefinitionProvider, - DefinitionPreviewProvider, -} from './types'; - -import invariant from 'assert'; -import {getLogger} from 'log4js'; -import {Range} from 'atom'; - -import analytics from 'nuclide-commons/analytics'; -import createPackage from 'nuclide-commons-atom/createPackage'; -import FeatureConfig from 'nuclide-commons-atom/feature-config'; -import {wordAtPosition} from 'nuclide-commons-atom/range'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import ProviderRegistry from 'nuclide-commons-atom/ProviderRegistry'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {goToLocation} from 'nuclide-commons-atom/go-to-location'; - -import DefinitionCache from './DefinitionCache'; -import getPreviewDatatipFromDefinitionResult from './getPreviewDatatipFromDefinitionResult'; - -class Activation { - _providers: ProviderRegistry; - _definitionPreviewProvider: ?DefinitionPreviewProvider; - _definitionCache: DefinitionCache; - _disposables: UniversalDisposable; - _triggerKeys: Set; - - constructor() { - this._providers = new ProviderRegistry(); - this._definitionCache = new DefinitionCache(); - this._triggerKeys = new Set(); - - this._disposables = new UniversalDisposable( - FeatureConfig.observe( - getPlatformKeys(process.platform), - (newValue: ?string) => { - this._triggerKeys = (new Set( - // flowlint-next-line sketchy-null-string:off - newValue ? newValue.split(',') : null, - ): Set); - }, - ), - ); } dispose() { this._disposables.dispose(); } - async _getDefinition( - editor: atom$TextEditor, - position: atom$Point, - ): Promise { - for (const provider of this._providers.getAllProvidersForEditor(editor)) { - try { - // eslint-disable-next-line no-await-in-loop - const result = await provider.getDefinition(editor, position); - if (result != null) { - if (result.queryRange == null) { - const match = wordAtPosition(editor, position, { - includeNonWordCharacters: false, - }); - result.queryRange = [ - match != null ? match.range : new Range(position, position), - ]; + _getDefinition( + editor, + position) + {var _this = this;return (0, _asyncToGenerator.default)(function* () { + for (const provider of _this._providers.getAllProvidersForEditor(editor)) { + try { + // eslint-disable-next-line no-await-in-loop + const result = yield provider.getDefinition(editor, position); + if (result != null) { + if (result.queryRange == null) { + const match = (0, (_range || _load_range()).wordAtPosition)(editor, position, { + includeNonWordCharacters: false }); + + result.queryRange = [ + match != null ? match.range : new _atom.Range(position, position)]; + + } + return result; } - return result; - } - } catch (err) { - getLogger('atom-ide-definitions').error( + } catch (err) { + (0, (_log4js || _load_log4js()).getLogger)('atom-ide-definitions').error( `Error getting definition for ${String(editor.getPath())}`, - err, - ); + err); + + } } - } - return null; + return null;})(); } - async getSuggestion( - editor: atom$TextEditor, - position: atom$Point, - ): Promise { - const result = await this._definitionCache.get(editor, position, () => - this._getDefinition(editor, position), - ); - - if (result == null) { - return null; - } - - const {queryRange, definitions} = result; - invariant(definitions.length > 0); - // queryRange might be null coming out of the provider, but the output - // of _getDefinition has ensured it's not null. - invariant(queryRange != null); - - function createCallback(definition) { - return () => { - goToLocation(definition.path, { - line: definition.position.row, - column: definition.position.column, - }); - analytics.track('go-to-definition', { - path: definition.path, - line: definition.position.row, - column: definition.position.column, - from: editor.getPath(), - }); - }; - } - - function createTitle(definition) { - const filePath = - definition.projectRoot == null - ? definition.path - : nuclideUri.relative(definition.projectRoot, definition.path); - if (definition.name == null) { - // Fall back to just displaying the path:line. - return `${filePath}:${definition.position.row + 1}`; + getSuggestion( + editor, + position) + {var _this2 = this;return (0, _asyncToGenerator.default)(function* () { + const result = yield _this2._definitionCache.get(editor, position, function () {return ( + _this2._getDefinition(editor, position));}); + + + if (result == null) { + return null; } - return `${definition.name} (${filePath})`; - } - - if (definitions.length === 1) { - return { - range: queryRange, - callback: createCallback(definitions[0]), - }; - } else { - return { - range: queryRange, - callback: definitions.map(definition => { - return { - title: createTitle(definition), - callback: createCallback(definition), - }; - }), - }; - } + + const { queryRange, definitions } = result;if (!( + definitions.length > 0)) {throw new Error('Invariant violation: "definitions.length > 0"');} + // queryRange might be null coming out of the provider, but the output + // of _getDefinition has ensured it's not null. + if (!(queryRange != null)) {throw new Error('Invariant violation: "queryRange != null"');} + + function createCallback(definition) { + return () => { + (0, (_goToLocation || _load_goToLocation()).goToLocation)(definition.path, { + line: definition.position.row, + column: definition.position.column }); + + (_analytics || _load_analytics()).default.track('go-to-definition', { + path: definition.path, + line: definition.position.row, + column: definition.position.column, + from: editor.getPath() }); + + }; + } + + function createTitle(definition) { + const filePath = + definition.projectRoot == null ? + definition.path : + (_nuclideUri || _load_nuclideUri()).default.relative(definition.projectRoot, definition.path); + if (definition.name == null) { + // Fall back to just displaying the path:line. + return `${filePath}:${definition.position.row + 1}`; + } + return `${definition.name} (${filePath})`; + } + + if (definitions.length === 1) { + return { + range: queryRange, + callback: createCallback(definitions[0]) }; + + } else { + return { + range: queryRange, + callback: definitions.map(function (definition) { + return { + title: createTitle(definition), + callback: createCallback(definition) }; + + }) }; + + }})(); } - async getPreview( - editor: atom$TextEditor, - position: atom$Point, - heldKeys: Set, - ): Promise { - if ( - !this._triggerKeys || + getPreview( + editor, + position, + heldKeys) + {var _this3 = this;return (0, _asyncToGenerator.default)(function* () { + if ( + !_this3._triggerKeys || // are the required keys held down? - !Array.from(this._triggerKeys).every(key => heldKeys.has(key)) - ) { - return; - } - - const result = await this._getDefinition(editor, position); - if (result == null) { - return null; - } - const queryRange = result.queryRange; - // queryRange might be null coming out of the provider, but the output - // of _getDefinition has ensured it's not null. - invariant(queryRange != null); - - const grammar = editor.getGrammar(); - const previewDatatip = getPreviewDatatipFromDefinitionResult( + !Array.from(_this3._triggerKeys).every(function (key) {return heldKeys.has(key);})) + { + return; + } + + const result = yield _this3._getDefinition(editor, position); + if (result == null) { + return null; + } + const queryRange = result.queryRange; + // queryRange might be null coming out of the provider, but the output + // of _getDefinition has ensured it's not null. + if (!(queryRange != null)) {throw new Error('Invariant violation: "queryRange != null"');} + + const grammar = editor.getGrammar(); + const previewDatatip = (0, (_getPreviewDatatipFromDefinitionResult || _load_getPreviewDatatipFromDefinitionResult()).default)( queryRange[0], result.definitions, - this._definitionPreviewProvider, - grammar, - ); - - // flowlint-next-line sketchy-null-mixed:off - if (previewDatatip != null && previewDatatip.markedStrings) { - analytics.track('hyperclick-preview-popup', { - grammar: grammar.name, - definitionCount: result.definitions.length, - }); - } - - return previewDatatip; + _this3._definitionPreviewProvider, + grammar); + + + // flowlint-next-line sketchy-null-mixed:off + if (previewDatatip != null && previewDatatip.markedStrings) { + (_analytics || _load_analytics()).default.track('hyperclick-preview-popup', { + grammar: grammar.name, + definitionCount: result.definitions.length }); + + } + + return previewDatatip;})(); } - consumeDefinitionProvider(provider: DefinitionProvider): IDisposable { + consumeDefinitionProvider(provider) { const disposable = this._providers.addProvider(provider); this._disposables.add(disposable); return disposable; } - consumeDefinitionPreviewProvider(provider: DefinitionPreviewProvider) { + consumeDefinitionPreviewProvider(provider) { this._definitionPreviewProvider = provider; } - consumeDatatipService(service: DatatipService): IDisposable { - const datatipProvider: ModifierDatatipProvider = { + consumeDatatipService(service) { + const datatipProvider = { providerName: 'hyperclick-preview', priority: 1, modifierDatatip: ( - editor: atom$TextEditor, - bufferPosition: atom$Point, - heldKeys: Set, - ) => this.getPreview(editor, bufferPosition, heldKeys), - }; + editor, + bufferPosition, + heldKeys) => + this.getPreview(editor, bufferPosition, heldKeys) }; + const disposable = service.addModifierProvider(datatipProvider); this._disposables.add(disposable); return disposable; } - getHyperclickProvider(): HyperclickProvider { + getHyperclickProvider() { return { priority: 20, providerName: 'atom-ide-definitions', - getSuggestion: (editor, position) => this.getSuggestion(editor, position), - }; - } -} + getSuggestion: (editor, position) => this.getSuggestion(editor, position) }; + + }} + function getPlatformKeys(platform) { if (platform === 'darwin') { @@ -253,4 +253,4 @@ function getPlatformKeys(platform) { return 'hyperclick.linuxTriggerKeys'; } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-definitions/lib/types.js b/modules/atom-ide-ui/pkg/atom-ide-definitions/lib/types.js index 65134d88..a726efc4 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-definitions/lib/types.js +++ b/modules/atom-ide-ui/pkg/atom-ide-definitions/lib/types.js @@ -1,64 +1 @@ -/** - * 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 - * @format - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -export type Definition = { - // Path of the file in which the definition is located. - path: NuclideUri, - // First character of the definition's identifier. - // e.g. "F" in `class Foo {}` - position: atom$Point, - // Optional: the range of the entire definition. - // e.g. "c" to "}" in `class Foo {}` - range?: atom$Range, - // Optional: `name` and `projectRoot` can be provided to display a more human-readable title - // inside of Hyperclick when there are multiple definitions. - name?: string, - // If provided, `projectRoot` will be used to display a relativized version of `path`. - projectRoot?: NuclideUri, - // `language` may be used by consumers to identify the source of definitions. - language: string, -}; - -// Definition queries supply a point. -// The returned queryRange is the range within which the returned definition is valid. -// Typically queryRange spans the containing identifier around the query point. -// (If a null queryRange is returned, the range of the word containing the point is used.) -export type DefinitionQueryResult = { - queryRange: ?Array, - definitions: Array, // Must be non-empty. -}; - -// Provides definitions for a set of language grammars. -export type DefinitionProvider = { - // If there are multiple providers for a given grammar, - // the one with the highest priority will be used. - priority: number, - grammarScopes: Array, - // Obtains the definition in an editor at the given point. - // This should return null if no definition is available. - getDefinition: ( - editor: TextEditor, - position: atom$Point, - ) => Promise, -}; - -export type DefinitionPreviewProvider = { - getDefinitionPreview( - definition: Definition, - ): Promise, -}; +'use strict'; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-definitions/spec/DefinitionHyperclick-spec.js b/modules/atom-ide-ui/pkg/atom-ide-definitions/spec/DefinitionHyperclick-spec.js index 17dc6cbc..48926e23 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-definitions/spec/DefinitionHyperclick-spec.js +++ b/modules/atom-ide-ui/pkg/atom-ide-definitions/spec/DefinitionHyperclick-spec.js @@ -1,57 +1,57 @@ -/** - * 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 - * @format - */ - -import type { - HyperclickProvider, - HyperclickSuggestion, -} from '../../hyperclick/lib/types'; -import type {DefinitionProvider} from '../lib/types'; - -import {Point, Range, TextEditor} from 'atom'; -import invariant from 'assert'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -describe('DefinitionHyperclick', () => { - let provider: ?HyperclickProvider; - const definitionProvider: DefinitionProvider = { - priority: 20, - name: '', - grammarScopes: ['text.plain.null-grammar'], - getDefinition: () => Promise.resolve(null), - }; - let editor: TextEditor; - const position = new Point(0, 0); +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + + + + + + + + + + + + + + + + + +var _atom = require('atom');var _UniversalDisposable; + +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */describe('DefinitionHyperclick', () => {let provider;const definitionProvider = { priority: 20, name: '', grammarScopes: ['text.plain.null-grammar'], getDefinition: () => Promise.resolve(null) };let editor; + const position = new _atom.Point(0, 0); let goToLocation; let disposables; beforeEach(() => { atom.packages.activatePackage('atom-ide-definitions'); - editor = new TextEditor(); + editor = new _atom.TextEditor(); goToLocation = spyOn( - require('nuclide-commons-atom/go-to-location'), - 'goToLocation', - ); - - disposables = new UniversalDisposable( - atom.packages.serviceHub.provide( - 'definitions', - '0.1.0', - definitionProvider, - ), - atom.packages.serviceHub.consume('hyperclick', '0.1.0', x => { - provider = x; - }), - ); + require('nuclide-commons-atom/go-to-location'), + 'goToLocation'); + + + disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default( + atom.packages.serviceHub.provide( + 'definitions', + '0.1.0', + definitionProvider), + + atom.packages.serviceHub.consume('hyperclick', '0.1.0', x => { + provider = x; + })); + }); afterEach(() => { @@ -59,112 +59,112 @@ describe('DefinitionHyperclick', () => { }); it('no definition service', () => { - waitsForPromise(async () => { - spyOn(editor, 'getGrammar').andReturn({scopeName: 'blah'}); - invariant(provider != null); - invariant(provider.getSuggestion != null); - const result = await provider.getSuggestion(editor, position); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + spyOn(editor, 'getGrammar').andReturn({ scopeName: 'blah' });if (!( + provider != null)) {throw new Error('Invariant violation: "provider != null"');}if (!( + provider.getSuggestion != null)) {throw new Error('Invariant violation: "provider.getSuggestion != null"');} + const result = yield provider.getSuggestion(editor, position); expect(result).toBe(null); - }); + })); }); it('no definition', () => { - waitsForPromise(async () => { - const spy = spyOn(definitionProvider, 'getDefinition').andReturn(null); - invariant(provider != null); - invariant(provider.getSuggestion != null); - const result = await provider.getSuggestion(editor, position); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const spy = spyOn(definitionProvider, 'getDefinition').andReturn(null);if (!( + provider != null)) {throw new Error('Invariant violation: "provider != null"');}if (!( + provider.getSuggestion != null)) {throw new Error('Invariant violation: "provider.getSuggestion != null"');} + const result = yield provider.getSuggestion(editor, position); expect(result).toBe(null); expect(spy).toHaveBeenCalledWith(editor, position); - }); + })); }); it('definition - single', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { const definition = { - queryRange: [new Range(new Point(1, 1), new Point(1, 5))], + queryRange: [new _atom.Range(new _atom.Point(1, 1), new _atom.Point(1, 5))], definitions: [ - { - path: 'path1', - position: new Point(1, 2), - range: null, - id: 'symbol-name', - name: null, - projectRoot: null, - }, - ], - }; + { + path: 'path1', + position: new _atom.Point(1, 2), + range: null, + id: 'symbol-name', + name: null, + projectRoot: null }] }; + + + const spy = spyOn(definitionProvider, 'getDefinition').andReturn( - Promise.resolve(definition), - ); + Promise.resolve(definition));if (!( + - invariant(provider != null); - invariant(provider.getSuggestion != null); - const result = await provider.getSuggestion(editor, position); + provider != null)) {throw new Error('Invariant violation: "provider != null"');}if (!( + provider.getSuggestion != null)) {throw new Error('Invariant violation: "provider.getSuggestion != null"');} + const result = yield provider.getSuggestion(editor, position);if (!( - invariant(result != null); + result != null)) {throw new Error('Invariant violation: "result != null"');} expect(result.range).toEqual(definition.queryRange); expect(spy).toHaveBeenCalledWith(editor, position); - expect(goToLocation).not.toHaveBeenCalled(); + expect(goToLocation).not.toHaveBeenCalled();if (!( - invariant(result != null); - invariant(result.callback != null); - invariant(typeof result.callback === 'function'); + result != null)) {throw new Error('Invariant violation: "result != null"');}if (!( + result.callback != null)) {throw new Error('Invariant violation: "result.callback != null"');}if (!( + typeof result.callback === 'function')) {throw new Error('Invariant violation: "typeof result.callback === \'function\'"');} result.callback(); - expect(goToLocation).toHaveBeenCalledWith('path1', {line: 1, column: 2}); - }); + expect(goToLocation).toHaveBeenCalledWith('path1', { line: 1, column: 2 }); + })); }); it('definition - multiple', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { const defs = { - queryRange: [new Range(new Point(1, 1), new Point(1, 5))], + queryRange: [new _atom.Range(new _atom.Point(1, 1), new _atom.Point(1, 5))], definitions: [ - { - path: '/a/b/path1', - position: new Point(1, 2), - range: null, - id: 'symbol-name', - name: 'd1', - projectRoot: '/a', - }, - { - path: '/a/b/path2', - position: new Point(3, 4), - range: null, - id: 'symbol-name2', - name: 'd2', - projectRoot: '/a', - }, - { - path: '/a/b/path3', - position: new Point(3, 4), - range: null, - id: 'symbol-without-name', - projectRoot: '/a', - }, - ], - }; + { + path: '/a/b/path1', + position: new _atom.Point(1, 2), + range: null, + id: 'symbol-name', + name: 'd1', + projectRoot: '/a' }, + + { + path: '/a/b/path2', + position: new _atom.Point(3, 4), + range: null, + id: 'symbol-name2', + name: 'd2', + projectRoot: '/a' }, + + { + path: '/a/b/path3', + position: new _atom.Point(3, 4), + range: null, + id: 'symbol-without-name', + projectRoot: '/a' }] }; + + + const spy = spyOn(definitionProvider, 'getDefinition').andReturn( - Promise.resolve(defs), - ); + Promise.resolve(defs));if (!( + + + provider != null)) {throw new Error('Invariant violation: "provider != null"');}if (!( + provider.getSuggestion != null)) {throw new Error('Invariant violation: "provider.getSuggestion != null"');} + const result = yield provider.getSuggestion( + editor, + position);if (!( - invariant(provider != null); - invariant(provider.getSuggestion != null); - const result: ?HyperclickSuggestion = await provider.getSuggestion( - editor, - position, - ); - invariant(result != null); + result != null)) {throw new Error('Invariant violation: "result != null"');} expect(result.range).toEqual(defs.queryRange); expect(spy).toHaveBeenCalledWith(editor, position); expect(goToLocation).not.toHaveBeenCalled(); - const callbacks: Array<{ - title: string, - callback: () => mixed, - }> = (result.callback: any); + const callbacks = + + + result.callback; expect(callbacks.length).toBe(3); expect(callbacks[0].title).toBe('d1 (b/path1)'); @@ -177,75 +177,75 @@ describe('DefinitionHyperclick', () => { callbacks[1].callback(); expect(goToLocation).toHaveBeenCalledWith('/a/b/path2', { line: 3, - column: 4, - }); - }); + column: 4 }); + + })); }); it('falls back to lower-priority providers', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { const def = { - queryRange: [new Range(new Point(1, 1), new Point(1, 5))], + queryRange: [new _atom.Range(new _atom.Point(1, 1), new _atom.Point(1, 5))], definitions: [ - { - path: 'path1', - position: new Point(1, 2), - range: null, - id: 'symbol-name', - name: null, - projectRoot: null, - }, - ], - }; + { + path: 'path1', + position: new _atom.Point(1, 2), + range: null, + id: 'symbol-name', + name: null, + projectRoot: null }] }; + + + const newProvider = { priority: 10, name: '', grammarScopes: ['text.plain.null-grammar'], - getDefinition: () => Promise.resolve(def), - }; - atom.packages.serviceHub.provide('definitions', '0.1.0', newProvider); - invariant(provider != null); - invariant(provider.getSuggestion != null); - const result = await provider.getSuggestion(editor, position); - expect(result).not.toBe(null); - invariant(result != null); + getDefinition: function () {return Promise.resolve(def);} }; + + atom.packages.serviceHub.provide('definitions', '0.1.0', newProvider);if (!( + provider != null)) {throw new Error('Invariant violation: "provider != null"');}if (!( + provider.getSuggestion != null)) {throw new Error('Invariant violation: "provider.getSuggestion != null"');} + const result = yield provider.getSuggestion(editor, position); + expect(result).not.toBe(null);if (!( + result != null)) {throw new Error('Invariant violation: "result != null"');} expect(result.range).toEqual(def.queryRange); - }); + })); }); it('does not cache null values', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { editor.setText('test'); const def = { - queryRange: [new Range(new Point(1, 1), new Point(1, 5))], + queryRange: [new _atom.Range(new _atom.Point(1, 1), new _atom.Point(1, 5))], definitions: [ - { - path: 'path1', - position: new Point(1, 2), - range: null, - id: 'symbol-name', - name: null, - projectRoot: null, - }, - ], - }; + { + path: 'path1', + position: new _atom.Point(1, 2), + range: null, + id: 'symbol-name', + name: null, + projectRoot: null }] }; + + + const newProvider = { priority: 10, name: '', grammarScopes: ['text.plain.null-grammar'], - getDefinition: () => Promise.resolve(null), - }; - atom.packages.serviceHub.provide('definitions', '0.1.0', newProvider); - invariant(provider != null); - invariant(provider.getSuggestion != null); - let result = await provider.getSuggestion(editor, position); + getDefinition: function () {return Promise.resolve(null);} }; + + atom.packages.serviceHub.provide('definitions', '0.1.0', newProvider);if (!( + provider != null)) {throw new Error('Invariant violation: "provider != null"');}if (!( + provider.getSuggestion != null)) {throw new Error('Invariant violation: "provider.getSuggestion != null"');} + let result = yield provider.getSuggestion(editor, position); expect(result).toBe(null); - newProvider.getDefinition = () => Promise.resolve(def); - invariant(provider.getSuggestion != null); - result = await provider.getSuggestion(editor, position); - invariant(result != null); + newProvider.getDefinition = function () {return Promise.resolve(def);};if (!( + provider.getSuggestion != null)) {throw new Error('Invariant violation: "provider.getSuggestion != null"');} + result = yield provider.getSuggestion(editor, position);if (!( + result != null)) {throw new Error('Invariant violation: "result != null"');} expect(result.range).toEqual(def.queryRange); - }); + })); }); -}); +}); \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/DiagnosticsViewModel.js b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/DiagnosticsViewModel.js index 6b0a0686..da78e6e1 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/DiagnosticsViewModel.js +++ b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/DiagnosticsViewModel.js @@ -1,141 +1,141 @@ -/** - * 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 - * @format - */ - -import type {IconName} from 'nuclide-commons-ui/Icon'; -import type {Props} from './ui/DiagnosticsView'; -import type {DiagnosticGroup, GlobalViewState} from './types'; -import type {DiagnosticMessage} from '../../atom-ide-diagnostics/lib/types'; -import type {RegExpFilterChange} from 'nuclide-commons-ui/RegExpFilter'; - -import dockForLocation from 'nuclide-commons-atom/dock-for-location'; -import {goToLocation} from 'nuclide-commons-atom/go-to-location'; -import memoizeUntilChanged from 'nuclide-commons/memoizeUntilChanged'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import observePaneItemVisibility from 'nuclide-commons-atom/observePaneItemVisibility'; -import {arrayEqual, areSetsEqual} from 'nuclide-commons/collection'; -import {fastDebounce} from 'nuclide-commons/observable'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import React from 'react'; -import analytics from 'nuclide-commons/analytics'; -import Model from 'nuclide-commons/Model'; -import {renderReactRoot} from 'nuclide-commons-ui/renderReactRoot'; -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import {Observable} from 'rxjs'; -import {getFilterPattern} from 'nuclide-commons-ui/RegExpFilter'; -import * as GroupUtils from './GroupUtils'; -import DiagnosticsView from './ui/DiagnosticsView'; - -type SerializedDiagnosticsViewModel = { - deserializer: 'atom-ide-ui.DiagnosticsViewModel', - state: { - hiddenGroups: Array, - }, -}; - -type State = {| - hiddenGroups: Set, - selectedMessage: ?DiagnosticMessage, - textFilter: {| - text: string, - isRegExp: boolean, - invalid: boolean, - pattern: ?RegExp, - |}, -|}; - -export const WORKSPACE_VIEW_URI = 'atom://nuclide/diagnostics'; - -export class DiagnosticsViewModel { - _element: ?HTMLElement; - _model: Model; - _props: Observable; - _disposables: IDisposable; - - constructor(globalStates: Observable) { +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.DiagnosticsViewModel = exports.WORKSPACE_VIEW_URI = undefined;var _dockForLocation; + + + + + + + + + + + + + + + + + +function _load_dockForLocation() {return _dockForLocation = _interopRequireDefault(require('nuclide-commons-atom/dock-for-location'));}var _goToLocation; +function _load_goToLocation() {return _goToLocation = require('nuclide-commons-atom/go-to-location');}var _memoizeUntilChanged; +function _load_memoizeUntilChanged() {return _memoizeUntilChanged = _interopRequireDefault(require('nuclide-commons/memoizeUntilChanged'));}var _nuclideUri; +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));}var _observePaneItemVisibility; +function _load_observePaneItemVisibility() {return _observePaneItemVisibility = _interopRequireDefault(require('nuclide-commons-atom/observePaneItemVisibility'));}var _collection; +function _load_collection() {return _collection = require('nuclide-commons/collection');}var _observable; +function _load_observable() {return _observable = require('nuclide-commons/observable');}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));} +var _react = _interopRequireDefault(require('react'));var _analytics; +function _load_analytics() {return _analytics = _interopRequireDefault(require('nuclide-commons/analytics'));}var _Model; +function _load_Model() {return _Model = _interopRequireDefault(require('nuclide-commons/Model'));}var _renderReactRoot; +function _load_renderReactRoot() {return _renderReactRoot = require('nuclide-commons-ui/renderReactRoot');}var _bindObservableAsProps; +function _load_bindObservableAsProps() {return _bindObservableAsProps = require('nuclide-commons-ui/bindObservableAsProps');} +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _RegExpFilter; +function _load_RegExpFilter() {return _RegExpFilter = require('nuclide-commons-ui/RegExpFilter');}var _GroupUtils; +function _load_GroupUtils() {return _GroupUtils = _interopRequireWildcard(require('./GroupUtils'));}var _DiagnosticsView; +function _load_DiagnosticsView() {return _DiagnosticsView = _interopRequireDefault(require('./ui/DiagnosticsView'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */ + + + + + + + + + +const WORKSPACE_VIEW_URI = exports.WORKSPACE_VIEW_URI = 'atom://nuclide/diagnostics'; + +class DiagnosticsViewModel { + + + + + + constructor(globalStates) {_initialiseProps.call(this); // Memoize `_filterDiagnostics()` - (this: any)._filterDiagnostics = memoizeUntilChanged( - this._filterDiagnostics, - (diagnostics, pattern, hiddenGroups, filterPath) => ({ - diagnostics, - pattern, - hiddenGroups, - filterPath, - }), - (a, b) => - patternsAreEqual(a.pattern, b.pattern) && - areSetsEqual(a.hiddenGroups, b.hiddenGroups) && - arrayEqual(a.diagnostics, b.diagnostics) && - a.filterPath === b.filterPath, - ); - - const {pattern, invalid} = getFilterPattern('', false); - this._model = new Model({ + this._filterDiagnostics = (0, (_memoizeUntilChanged || _load_memoizeUntilChanged()).default)( + this._filterDiagnostics, + (diagnostics, pattern, hiddenGroups, filterPath) => ({ + diagnostics, + pattern, + hiddenGroups, + filterPath }), + + (a, b) => + patternsAreEqual(a.pattern, b.pattern) && + (0, (_collection || _load_collection()).areSetsEqual)(a.hiddenGroups, b.hiddenGroups) && + (0, (_collection || _load_collection()).arrayEqual)(a.diagnostics, b.diagnostics) && + a.filterPath === b.filterPath); + + + const { pattern, invalid } = (0, (_RegExpFilter || _load_RegExpFilter()).getFilterPattern)('', false); + this._model = new (_Model || _load_Model()).default({ // TODO: Get this from constructor/serialization. hiddenGroups: new Set(), - textFilter: {text: '', isRegExp: false, pattern, invalid}, - selectedMessage: null, - }); - const visibility = observePaneItemVisibility(this).distinctUntilChanged(); - this._disposables = new UniversalDisposable( - visibility - .let(fastDebounce(1000)) - .distinctUntilChanged() - .filter(Boolean) - .subscribe(() => { - analytics.track('diagnostics-show-table'); - }), - ); + textFilter: { text: '', isRegExp: false, pattern, invalid }, + selectedMessage: null }); + + const visibility = (0, (_observePaneItemVisibility || _load_observePaneItemVisibility()).default)(this).distinctUntilChanged(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default( + visibility. + let((0, (_observable || _load_observable()).fastDebounce)(1000)). + distinctUntilChanged(). + filter(Boolean). + subscribe(() => { + (_analytics || _load_analytics()).default.track('diagnostics-show-table'); + })); + // Combine the state that's shared between instances, the state that's unique to this instance, // and unchanging callbacks, to get the props for our component. - const props = Observable.combineLatest( - globalStates, - this._model.toObservable(), - visibility, - (globalState, instanceState, isVisible) => ({ - ...globalState, - ...instanceState, - isVisible, - diagnostics: this._filterDiagnostics( - globalState.diagnostics, - instanceState.textFilter.pattern, - instanceState.hiddenGroups, - globalState.filterByActiveTextEditor - ? globalState.pathToActiveTextEditor - : null, - ), - onTypeFilterChange: this._handleTypeFilterChange, - onTextFilterChange: this._handleTextFilterChange, - selectMessage: this._selectMessage, - gotoMessageLocation: goToDiagnosticLocation, - supportedMessageKinds: globalState.supportedMessageKinds, - }), - ); + const props = _rxjsBundlesRxMinJs.Observable.combineLatest( + globalStates, + this._model.toObservable(), + visibility, + (globalState, instanceState, isVisible) => Object.assign({}, + globalState, + instanceState, { + isVisible, + diagnostics: this._filterDiagnostics( + globalState.diagnostics, + instanceState.textFilter.pattern, + instanceState.hiddenGroups, + globalState.filterByActiveTextEditor ? + globalState.pathToActiveTextEditor : + null), + + onTypeFilterChange: this._handleTypeFilterChange, + onTextFilterChange: this._handleTextFilterChange, + selectMessage: this._selectMessage, + gotoMessageLocation: goToDiagnosticLocation, + supportedMessageKinds: globalState.supportedMessageKinds })); + + this._props = this._trackVisibility(props); } // If autoVisibility setting is on, then automatically show/hide on changes. - _trackVisibility(props: Observable): Observable { + _trackVisibility(props) { let lastDiagnostics = []; return props.do(newProps => { if ( - newProps.autoVisibility && - !arrayEqual( - newProps.diagnostics, - lastDiagnostics, - (a, b) => a.text === b.text, - ) - ) { + newProps.autoVisibility && + !(0, (_collection || _load_collection()).arrayEqual)( + newProps.diagnostics, + lastDiagnostics, + (a, b) => a.text === b.text)) + + { const pane = atom.workspace.paneForItem(this); if (newProps.diagnostics.length > 0 && !newProps.isVisible) { // We want to call workspace.open but it has no option to @@ -144,7 +144,7 @@ export class DiagnosticsViewModel { // https://github.com/atom/atom/issues/16007 if (pane != null) { pane.activateItem(this); - const dock = dockForLocation(pane.getContainer().getLocation()); + const dock = (0, (_dockForLocation || _load_dockForLocation()).default)(pane.getContainer().getLocation()); if (dock != null) { dock.show(); } @@ -154,9 +154,9 @@ export class DiagnosticsViewModel { if (pane != null) { const items = pane.getItems(); if ( - items.length === 1 && - items[0] instanceof DiagnosticsViewModel - ) { + items.length === 1 && + items[0] instanceof DiagnosticsViewModel) + { atom.workspace.hide(this); } } @@ -166,40 +166,40 @@ export class DiagnosticsViewModel { }); } - destroy(): void { + destroy() { this._disposables.dispose(); } - getTitle(): string { + getTitle() { return 'Diagnostics'; } - getIconName(): IconName { + getIconName() { return 'law'; } - getURI(): string { + getURI() { return WORKSPACE_VIEW_URI; } - getDefaultLocation(): string { + getDefaultLocation() { return 'bottom'; } - serialize(): SerializedDiagnosticsViewModel { - const {hiddenGroups} = this._model.state; + serialize() { + const { hiddenGroups } = this._model.state; return { deserializer: 'atom-ide-ui.DiagnosticsViewModel', state: { - hiddenGroups: [...hiddenGroups], - }, - }; + hiddenGroups: [...hiddenGroups] } }; + + } - getElement(): HTMLElement { + getElement() { if (this._element == null) { - const Component = bindObservableAsProps(this._props, DiagnosticsView); - const element = renderReactRoot(); + const Component = (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)(this._props, (_DiagnosticsView || _load_DiagnosticsView()).default); + const element = (0, (_renderReactRoot || _load_renderReactRoot()).renderReactRoot)(_react.default.createElement(Component, null)); element.classList.add('diagnostics-ui'); this._element = element; } @@ -207,39 +207,39 @@ export class DiagnosticsViewModel { } /** - * Toggle the filter. - */ - _handleTypeFilterChange = (type: DiagnosticGroup): void => { - const {hiddenGroups} = this._model.state; - const hidden = hiddenGroups.has(type); - const nextHiddenTypes = new Set(hiddenGroups); - if (hidden) { - nextHiddenTypes.delete(type); - } else { - nextHiddenTypes.add(type); - } - this._model.setState({hiddenGroups: nextHiddenTypes}); - analytics.track('diagnostics-panel-change-filter'); - }; - - _handleTextFilterChange = (value: RegExpFilterChange): void => { - const {text, isRegExp} = value; - // TODO: Fuzzy if !isRegExp? - const {invalid, pattern} = getFilterPattern(text, isRegExp); - this._model.setState({ - textFilter: {text, isRegExp, invalid, pattern}, - }); - analytics.track('diagnostics-panel-change-filter'); - }; + * Toggle the filter. + */ + + + + + + + + + + + + + + + + + + + + + + _filterDiagnostics( - diagnostics: Array, - pattern: ?RegExp, - hiddenGroups: Set, - filterByPath: ?string, - ): Array { + diagnostics, + pattern, + hiddenGroups, + filterByPath) + { return diagnostics.filter(message => { - if (hiddenGroups.has(GroupUtils.getGroup(message))) { + if (hiddenGroups.has((_GroupUtils || _load_GroupUtils()).getGroup(message))) { return false; } if (filterByPath != null && message.filePath !== filterByPath) { @@ -249,44 +249,44 @@ export class DiagnosticsViewModel { return true; } return ( - (message.text != null && pattern.test(message.text)) || - (message.html != null && pattern.test(message.html)) || + message.text != null && pattern.test(message.text) || + message.html != null && pattern.test(message.html) || pattern.test(message.providerName) || - pattern.test(message.filePath) - ); + pattern.test(message.filePath)); + }); - } + }}exports.DiagnosticsViewModel = DiagnosticsViewModel;var _initialiseProps = function () {this._handleTypeFilterChange = type => {const { hiddenGroups } = this._model.state;const hidden = hiddenGroups.has(type);const nextHiddenTypes = new Set(hiddenGroups);if (hidden) {nextHiddenTypes.delete(type);} else {nextHiddenTypes.add(type);}this._model.setState({ hiddenGroups: nextHiddenTypes });(_analytics || _load_analytics()).default.track('diagnostics-panel-change-filter');};this._handleTextFilterChange = value => {const { text, isRegExp } = value; // TODO: Fuzzy if !isRegExp? + const { invalid, pattern } = (0, (_RegExpFilter || _load_RegExpFilter()).getFilterPattern)(text, isRegExp);this._model.setState({ textFilter: { text, isRegExp, invalid, pattern } });(_analytics || _load_analytics()).default.track('diagnostics-panel-change-filter');};this. + _selectMessage = message => { + this._model.setState({ selectedMessage: message }); + };}; - _selectMessage = (message: DiagnosticMessage): void => { - this._model.setState({selectedMessage: message}); - }; -} function goToDiagnosticLocation( - message: DiagnosticMessage, - options: {|focusEditor: boolean|}, -): void { +message, +options) +{ // TODO: what should we do for project-path diagnostics? - if (nuclideUri.endsWithSeparator(message.filePath)) { + if ((_nuclideUri || _load_nuclideUri()).default.endsWithSeparator(message.filePath)) { return; } - analytics.track('diagnostics-panel-goto-location'); + (_analytics || _load_analytics()).default.track('diagnostics-panel-goto-location'); const uri = message.filePath; // If initialLine is N, Atom will navigate to line N+1. // Flow sometimes reports a row of -1, so this ensures the line is at least one. const line = Math.max(message.range ? message.range.start.row : 0, 0); const column = 0; - goToLocation(uri, { + (0, (_goToLocation || _load_goToLocation()).goToLocation)(uri, { line, column, activatePane: options.focusEditor, - pending: true, - }); + pending: true }); + } -function patternsAreEqual(a: ?RegExp, b: ?RegExp) { +function patternsAreEqual(a, b) { if (a === b) { return true; } @@ -300,6 +300,6 @@ function patternsAreEqual(a: ?RegExp, b: ?RegExp) { a.source === b.source && a.global === b.global && a.multiline === b.multiline && - a.ignoreCase === b.ignoreCase - ); -} + a.ignoreCase === b.ignoreCase); + +} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/GroupUtils.js b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/GroupUtils.js index 9cc7925e..adb8d7cc 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/GroupUtils.js +++ b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/GroupUtils.js @@ -1,101 +1,103 @@ -/** - * 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 - * @format - */ - -import type {IconName} from 'nuclide-commons-ui/Icon'; -import type {DiagnosticMessage} from '../../atom-ide-diagnostics/lib/types'; -import type {DiagnosticGroup} from './types'; - -import invariant from 'assert'; - -const PRIORITIZED_GROUPS: Array = [ - 'review', - 'errors', - 'warnings', - 'info', - 'action', -]; - -export function getGroup(message: DiagnosticMessage): DiagnosticGroup { - const {kind} = message; - switch (kind) { - case 'lint': - case null: - case undefined: - invariant(message.type !== 'Hint'); - // We have a separate button for each severity. - switch (message.type) { - case 'Error': - return 'errors'; - case 'Warning': - return 'warnings'; - case 'Info': - return 'info'; - default: - (message.type: empty); - throw new Error(`Invalid message severity: ${message.type}`); - } - case 'review': - return 'review'; - case 'action': - return 'action'; - default: - (kind: empty); - throw new Error(`Invalid message kind: ${kind}`); - } -} - -export function getDisplayName(group: DiagnosticGroup): string { - switch (group) { - case 'errors': - return 'Errors'; - case 'warnings': - return 'Warnings'; - case 'info': - return 'Info'; - case 'review': - return 'Review'; - case 'action': - return 'Actions'; - default: - (group: empty); - throw new Error(`Invalid group: ${group}`); - } -} - -export function getIcon(group: DiagnosticGroup): IconName { - switch (group) { - case 'errors': - return 'nuclicon-error'; - case 'warnings': - return 'nuclicon-warning'; - case 'info': - return 'info'; - case 'review': - return 'nuclicon-comment-discussion'; - case 'action': - return 'nuclicon-lightbulb-filled'; - default: - (group: empty); - throw new Error(`Invalid filter type: ${group}`); - } -} - -export function getHighestPriorityGroup( - groups: Set, -): DiagnosticGroup { - for (const group of PRIORITIZED_GROUPS) { - if (groups.has(group)) { - return group; - } - } - throw new Error(`Invalid group set: ${[...groups].toString()}`); -} +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + + + + + + + + + + + + + +getGroup = getGroup;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + +getDisplayName = getDisplayName;exports. + + + + + + + + + + + + + + + + + +getIcon = getIcon;exports. + + + + + + + + + + + + + + + + + +getHighestPriorityGroup = getHighestPriorityGroup; /** + * 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. + * + * + * @format + */const PRIORITIZED_GROUPS = ['review', 'errors', 'warnings', 'info', 'action'];function getGroup(message) {const { kind } = message;switch (kind) {case 'lint':case null:case undefined:if (!(message.type !== 'Hint')) {throw new Error('Invariant violation: "message.type !== \'Hint\'"');} // We have a separate button for each severity. + switch (message.type) {case 'Error':return 'errors';case 'Warning':return 'warnings';case 'Info':return 'info';default:message.type;throw new Error(`Invalid message severity: ${message.type}`);}case 'review':return 'review';case 'action':return 'action';default:kind;throw new Error(`Invalid message kind: ${kind}`);}}function getDisplayName(group) {switch (group) {case 'errors':return 'Errors';case 'warnings':return 'Warnings';case 'info':return 'Info';case 'review':return 'Review';case 'action':return 'Actions';default:group;throw new Error(`Invalid group: ${group}`);}}function getIcon(group) {switch (group) {case 'errors':return 'nuclicon-error';case 'warnings':return 'nuclicon-warning';case 'info':return 'info';case 'review':return 'nuclicon-comment-discussion';case 'action':return 'nuclicon-lightbulb-filled';default:group;throw new Error(`Invalid filter type: ${group}`);}}function getHighestPriorityGroup(groups) {for (const group of PRIORITIZED_GROUPS) {if (groups.has(group)) {return group;}}throw new Error(`Invalid group set: ${[...groups].toString()}`);} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/KeyboardShortcuts.js b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/KeyboardShortcuts.js index 60875b93..6e5f9f4f 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/KeyboardShortcuts.js +++ b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/KeyboardShortcuts.js @@ -1,91 +1,91 @@ -/** - * 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 - * @format - */ - -import type { - DiagnosticTrace, - DiagnosticMessage, - DiagnosticUpdater, -} from '../../atom-ide-diagnostics/lib/types'; - -import invariant from 'assert'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {goToLocation} from 'nuclide-commons-atom/go-to-location'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _UniversalDisposable; + + + + + + + + + + + + + + + + + + +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _goToLocation; +function _load_goToLocation() {return _goToLocation = require('nuclide-commons-atom/go-to-location');}var _event; +function _load_event() {return _event = require('nuclide-commons/event');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} // TODO(peterhal): The current index should really live in the DiagnosticStore. -export default class KeyboardShortcuts { - _subscriptions: UniversalDisposable; - _diagnostics: Array; - _index: ?number; - _traceIndex: ?number; +class KeyboardShortcuts { + + + - constructor(diagnosticUpdater: DiagnosticUpdater) { + + constructor(diagnosticUpdater) { this._index = null; this._diagnostics = []; - this._subscriptions = new UniversalDisposable(); + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); const first = () => this.setIndex(0); const last = () => this.setIndex(this._diagnostics.length - 1); this._subscriptions.add( - observableFromSubscribeFunction( - diagnosticUpdater.observeMessages, - ).subscribe(diagnostics => { - this._index = null; - this._traceIndex = null; - this._diagnostics = diagnostics; - }), - atom.commands.add( - 'atom-workspace', - 'diagnostics:go-to-first-diagnostic', - first, - ), - atom.commands.add( - 'atom-workspace', - 'diagnostics:go-to-last-diagnostic', - last, - ), - atom.commands.add( - 'atom-workspace', - 'diagnostics:go-to-next-diagnostic', - () => { - this._index == null ? first() : this.setIndex(this._index + 1); - }, - ), - atom.commands.add( - 'atom-workspace', - 'diagnostics:go-to-previous-diagnostic', - () => { - this._index == null ? last() : this.setIndex(this._index - 1); - }, - ), - atom.commands.add( - 'atom-workspace', - 'diagnostics:go-to-next-diagnostic-trace', - () => { - this.nextTrace(); - }, - ), - atom.commands.add( - 'atom-workspace', - 'diagnostics:go-to-previous-diagnostic-trace', - () => { - this.previousTrace(); - }, - ), - ); + (0, (_event || _load_event()).observableFromSubscribeFunction)( + diagnosticUpdater.observeMessages). + subscribe(diagnostics => { + this._index = null; + this._traceIndex = null; + this._diagnostics = diagnostics; + }), + atom.commands.add( + 'atom-workspace', + 'diagnostics:go-to-first-diagnostic', + first), + + atom.commands.add( + 'atom-workspace', + 'diagnostics:go-to-last-diagnostic', + last), + + atom.commands.add( + 'atom-workspace', + 'diagnostics:go-to-next-diagnostic', + () => { + this._index == null ? first() : this.setIndex(this._index + 1); + }), + + atom.commands.add( + 'atom-workspace', + 'diagnostics:go-to-previous-diagnostic', + () => { + this._index == null ? last() : this.setIndex(this._index - 1); + }), + + atom.commands.add( + 'atom-workspace', + 'diagnostics:go-to-next-diagnostic-trace', + () => { + this.nextTrace(); + }), + + atom.commands.add( + 'atom-workspace', + 'diagnostics:go-to-previous-diagnostic-trace', + () => { + this.previousTrace(); + })); + + } - setIndex(index: number): void { + setIndex(index) { this._traceIndex = null; if (this._diagnostics.length === 0) { this._index = null; @@ -95,22 +95,22 @@ export default class KeyboardShortcuts { this.gotoCurrentIndex(); } - gotoCurrentIndex(): void { - invariant(this._index != null); - invariant(this._traceIndex == null); + gotoCurrentIndex() {if (!( + this._index != null)) {throw new Error('Invariant violation: "this._index != null"');}if (!( + this._traceIndex == null)) {throw new Error('Invariant violation: "this._traceIndex == null"');} const diagnostic = this._diagnostics[this._index]; const range = diagnostic.range; if (range == null) { - goToLocation(diagnostic.filePath); + (0, (_goToLocation || _load_goToLocation()).goToLocation)(diagnostic.filePath); } else { - goToLocation(diagnostic.filePath, { + (0, (_goToLocation || _load_goToLocation()).goToLocation)(diagnostic.filePath, { line: range.start.row, - column: range.start.column, - }); + column: range.start.column }); + } } - nextTrace(): void { + nextTrace() { const traces = this.currentTraces(); if (traces == null) { return; @@ -126,13 +126,13 @@ export default class KeyboardShortcuts { this.gotoCurrentIndex(); } - previousTrace(): void { + previousTrace() { const traces = this.currentTraces(); if (traces == null) { return; } let candidateTrace = - this._traceIndex == null ? traces.length - 1 : this._traceIndex - 1; + this._traceIndex == null ? traces.length - 1 : this._traceIndex - 1; while (candidateTrace >= 0) { if (this.trySetCurrentTrace(traces, candidateTrace)) { return; @@ -143,7 +143,7 @@ export default class KeyboardShortcuts { this.gotoCurrentIndex(); } - currentTraces(): ?Array { + currentTraces() { if (this._index == null) { return null; } @@ -153,22 +153,31 @@ export default class KeyboardShortcuts { // TODO: Should filter out traces whose location matches the main diagnostic's location? trySetCurrentTrace( - traces: Array, - traceIndex: number, - ): boolean { + traces, + traceIndex) + { const trace = traces[traceIndex]; if (trace.filePath != null && trace.range != null) { this._traceIndex = traceIndex; - goToLocation(trace.filePath, { + (0, (_goToLocation || _load_goToLocation()).goToLocation)(trace.filePath, { line: trace.range.start.row, - column: trace.range.start.column, - }); + column: trace.range.start.column }); + return true; } return false; } - dispose(): void { + dispose() { this._subscriptions.dispose(); - } -} + }}exports.default = KeyboardShortcuts; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/aim.js b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/aim.js index 567e663d..806e2b04 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/aim.js +++ b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/aim.js @@ -1,83 +1,87 @@ -/** - * 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 - * @format - */ - -import {Observable} from 'rxjs'; - -type Point = {x: number, y: number}; - -const VECTOR_DURATION = 100; - -const distance = (a: Point, b: Point): number => { - return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2)); -}; - -const eventToPoint = (e: MouseEvent): Point => ({ - x: e.clientX, - y: e.clientY, -}); - -// Combine mouseenter and mouseleave to create an observable of hovering state. -function areHovering(element: HTMLElement): Observable { - return Observable.merge( - Observable.fromEvent(element, 'mouseenter').mapTo(true), - Observable.fromEvent(element, 'mouseleave').mapTo(false), - ); -} - -function findCorners(node: HTMLElement): [Point, Point, Point, Point] { - const {left, width, top, height} = node.getBoundingClientRect(); - return [ - {x: left, y: top}, // Top left - {x: left + width, y: top}, // Top right - {x: left, y: top + height}, // Bottom left - {x: left + width, y: top + height}, // Bottom right - ]; -} - -function areAiming(from: HTMLElement, to: HTMLElement): Observable { - const [topLeft, topRight, bottomLeft, bottomRight] = findCorners(to); - - const toBelowFrom = - to.getBoundingClientRect().top >= from.getBoundingClientRect().bottom; - - // For now we assume that `to` is always to the right of `from` and that +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +hoveringOrAiming = hoveringOrAiming;var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');const VECTOR_DURATION = 100; /** + * 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. + * + * + * @format + */const distance = (a, b) => {return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));};const eventToPoint = e => ({ x: e.clientX, y: e.clientY }); // Combine mouseenter and mouseleave to create an observable of hovering state. +function areHovering(element) {return _rxjsBundlesRxMinJs.Observable.merge(_rxjsBundlesRxMinJs.Observable.fromEvent(element, 'mouseenter').mapTo(true), _rxjsBundlesRxMinJs.Observable.fromEvent(element, 'mouseleave').mapTo(false));}function findCorners(node) {const { left, width, top, height } = node.getBoundingClientRect();return [{ x: left, y: top }, // Top left + { x: left + width, y: top }, // Top right + { x: left, y: top + height }, // Bottom left + { x: left + width, y: top + height }];}function areAiming(from, to) {const [topLeft, topRight, bottomLeft, bottomRight] = findCorners(to);const toBelowFrom = to.getBoundingClientRect().top >= from.getBoundingClientRect().bottom; // For now we assume that `to` is always to the right of `from` and that // `from` is always strictly above or below `to`. A more robust solution would // be to find the two corner of `to` that form the largest angle from the // center of `from` - const [cornerA, cornerB] = toBelowFrom - ? [topRight, bottomLeft] - : [topLeft, bottomRight]; - - return Observable.fromEvent(document, 'mousemove') - .map(eventToPoint) - .auditTime(VECTOR_DURATION) - .map(mouse => distance(mouse, cornerA) + distance(mouse, cornerB)) - .pairwise() - .map(([prevDist, currentDist]) => prevDist > currentDist) - .distinctUntilChanged(); -} - -export function hoveringOrAiming( - from: HTMLElement, - to: HTMLElement, -): Observable { - return Observable.concat( - areHovering(from) - .startWith(true) - .takeWhile(Boolean), - Observable.combineLatest( - areAiming(from, to).startWith(true), - areHovering(to).startWith(false), - (aiming, hovering) => aiming || hovering, - ), - ).distinctUntilChanged(); -} + const [cornerA, cornerB] = toBelowFrom ? [topRight, bottomLeft] : [topLeft, bottomRight];return _rxjsBundlesRxMinJs.Observable.fromEvent(document, 'mousemove').map(eventToPoint).auditTime(VECTOR_DURATION).map(mouse => distance(mouse, cornerA) + distance(mouse, cornerB)).pairwise().map(([prevDist, currentDist]) => prevDist > currentDist).distinctUntilChanged();}function hoveringOrAiming(from, to) {return _rxjsBundlesRxMinJs.Observable.concat(areHovering(from).startWith(true).takeWhile(Boolean), _rxjsBundlesRxMinJs.Observable.combineLatest(areAiming(from, to).startWith(true), areHovering(to).startWith(false), (aiming, hovering) => aiming || hovering)).distinctUntilChanged();} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/getDiagnosticDatatip.js b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/getDiagnosticDatatip.js index edb1e6bc..043c07f4 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/getDiagnosticDatatip.js +++ b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/getDiagnosticDatatip.js @@ -1,65 +1,65 @@ -/** - * 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 - * @format - */ - -import type {Datatip} from '../../atom-ide-datatip/lib/types'; -import type { - DiagnosticUpdater, - DiagnosticMessage, -} from '../../atom-ide-diagnostics/lib/types'; - -import invariant from 'assert'; -import * as React from 'react'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import {goToLocation} from 'nuclide-commons-atom/go-to-location'; -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import {DiagnosticsPopup} from './ui/DiagnosticsPopup'; - -const gotoLine = (file: string, line: number) => goToLocation(file, {line}); - -function makeDatatipComponent( - messages: Array, - diagnosticUpdater: DiagnosticUpdater, -): React.ComponentType<*> { - const fixer = message => diagnosticUpdater.applyFix(message); - return bindObservableAsProps( - observableFromSubscribeFunction(cb => - diagnosticUpdater.observeCodeActionsForMessage(cb), - ).map(codeActionsForMessage => ({ - messages, - fixer, - goToLocation: gotoLine, - codeActionsForMessage, - })), - DiagnosticsPopup, - ); -} - -export default (async function getDiagnosticDatatip( - editor: TextEditor, - position: atom$Point, - messagesAtPosition: Array, - diagnosticUpdater: DiagnosticUpdater, -): Promise { - let range = null; - for (const message of messagesAtPosition) { - if (message.range != null) { - range = range == null ? message.range : message.range.union(range); +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + + + + + + + + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react'));var _event; +function _load_event() {return _event = require('nuclide-commons/event');}var _goToLocation; +function _load_goToLocation() {return _goToLocation = require('nuclide-commons-atom/go-to-location');}var _bindObservableAsProps; +function _load_bindObservableAsProps() {return _bindObservableAsProps = require('nuclide-commons-ui/bindObservableAsProps');}var _DiagnosticsPopup; +function _load_DiagnosticsPopup() {return _DiagnosticsPopup = require('./ui/DiagnosticsPopup');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +const gotoLine = (file, line) => (0, (_goToLocation || _load_goToLocation()).goToLocation)(file, { line }); /** + * 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. + * + * + * @format + */function makeDatatipComponent(messages, diagnosticUpdater) {const fixer = message => diagnosticUpdater.applyFix(message);return (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)((0, (_event || _load_event()).observableFromSubscribeFunction)(cb => diagnosticUpdater.observeCodeActionsForMessage(cb)).map(codeActionsForMessage => ({ + messages, + fixer, + goToLocation: gotoLine, + codeActionsForMessage })), (_DiagnosticsPopup || _load_DiagnosticsPopup()).DiagnosticsPopup); + + + +}exports.default = (() => {var _ref = (0, _asyncToGenerator.default)( + + function* ( + editor, + position, + messagesAtPosition, + diagnosticUpdater) + { + let range = null; + for (const message of messagesAtPosition) { + if (message.range != null) { + range = range == null ? message.range : message.range.union(range); + } } - } - diagnosticUpdater.fetchCodeActions(editor, messagesAtPosition); - invariant(range != null); - return { - component: makeDatatipComponent(messagesAtPosition, diagnosticUpdater), - pinnable: false, - range, - }; -}); + diagnosticUpdater.fetchCodeActions(editor, messagesAtPosition);if (!( + range != null)) {throw new Error('Invariant violation: "range != null"');} + return { + component: makeDatatipComponent(messagesAtPosition, diagnosticUpdater), + pinnable: false, + range }; + + });function getDiagnosticDatatip(_x, _x2, _x3, _x4) {return _ref.apply(this, arguments);}return getDiagnosticDatatip;})(); \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/gutter.js b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/gutter.js index f632c78d..2f86045a 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/gutter.js +++ b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/gutter.js @@ -1,41 +1,82 @@ -/** - * 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 - * @format - */ - -import type { - DiagnosticUpdater, - DiagnosticMessage, - DiagnosticMessages, -} from '../../atom-ide-diagnostics/lib/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import classnames from 'classnames'; -import {Range} from 'atom'; -import invariant from 'assert'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import {completingSwitchMap} from 'nuclide-commons/observable'; -import {goToLocation as atomGoToLocation} from 'nuclide-commons-atom/go-to-location'; -import {wordAtPosition} from 'nuclide-commons-atom/range'; -import analytics from 'nuclide-commons/analytics'; -import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps'; -import {Observable} from 'rxjs'; -import {DiagnosticsPopup} from './ui/DiagnosticsPopup'; -import * as GroupUtils from './GroupUtils'; -import {hoveringOrAiming} from './aim'; - -const GUTTER_ID = 'diagnostics-gutter'; - -// TODO(mbolin): Make it so that when mousing over an element with this CSS class (or specifically, +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +applyUpdateToEditor = applyUpdateToEditor;var _classnames;function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));}var _atom = require('atom');var _react = _interopRequireWildcard(require('react'));var _reactDom = _interopRequireDefault(require('react-dom'));var _event;function _load_event() {return _event = require('nuclide-commons/event');}var _observable;function _load_observable() {return _observable = require('nuclide-commons/observable');}var _goToLocation;function _load_goToLocation() {return _goToLocation = require('nuclide-commons-atom/go-to-location');}var _range;function _load_range() {return _range = require('nuclide-commons-atom/range');}var _analytics;function _load_analytics() {return _analytics = _interopRequireDefault(require('nuclide-commons/analytics'));}var _bindObservableAsProps;function _load_bindObservableAsProps() {return _bindObservableAsProps = require('nuclide-commons-ui/bindObservableAsProps');}var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _DiagnosticsPopup;function _load_DiagnosticsPopup() {return _DiagnosticsPopup = require('./ui/DiagnosticsPopup');}var _GroupUtils;function _load_GroupUtils() {return _GroupUtils = _interopRequireWildcard(require('./GroupUtils'));}var _aim;function _load_aim() {return _aim = require('./aim');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */const GUTTER_ID = 'diagnostics-gutter'; // TODO(mbolin): Make it so that when mousing over an element with this CSS class (or specifically, // the child element with the "region" CSS class), we also do a showPopupFor(). This seems to be // tricky given how the DOM of a TextEditor works today. There are div.tile elements, each of which // has its own div.highlights element and many div.line elements. The div.highlights element has 0 @@ -45,65 +86,24 @@ const GUTTER_ID = 'diagnostics-gutter'; // might have to listen for mouseover events on TextEditor and then use its own APIs, such as // decorationsForScreenRowRange(), to see if there is a hit target instead. Since this will be // happening onmousemove, we also have to be careful to make sure this is not expensive. -const HIGHLIGHT_CSS = 'diagnostics-gutter-ui-highlight'; - -const HIGHLIGHT_CSS_LEVELS = { - Error: 'diagnostics-gutter-ui-highlight-error', - Warning: 'diagnostics-gutter-ui-highlight-warning', - Info: 'diagnostics-gutter-ui-highlight-info', - Hint: '', -}; - -const GUTTER_CSS_GROUPS = { - review: 'diagnostics-gutter-ui-gutter-review', - errors: 'diagnostics-gutter-ui-gutter-error', - warnings: 'diagnostics-gutter-ui-gutter-warning', - info: 'diagnostics-gutter-ui-gutter-info', - action: 'diagnostics-gutter-ui-gutter-action', - hidden: '', -}; - -const editorToMarkers: WeakMap> = new WeakMap(); -const itemToEditor: WeakMap = new WeakMap(); - -export function applyUpdateToEditor( - editor: TextEditor, - update: DiagnosticMessages, - diagnosticUpdater: DiagnosticUpdater, -): void { - let gutter = editor.gutterWithName(GUTTER_ID); - if (!gutter) { - // TODO(jessicalin): Determine an appropriate priority so that the gutter: +const HIGHLIGHT_CSS = 'diagnostics-gutter-ui-highlight';const HIGHLIGHT_CSS_LEVELS = { Error: 'diagnostics-gutter-ui-highlight-error', Warning: 'diagnostics-gutter-ui-highlight-warning', Info: 'diagnostics-gutter-ui-highlight-info', Hint: '' };const GUTTER_CSS_GROUPS = { review: 'diagnostics-gutter-ui-gutter-review', errors: 'diagnostics-gutter-ui-gutter-error', warnings: 'diagnostics-gutter-ui-gutter-warning', info: 'diagnostics-gutter-ui-gutter-info', action: 'diagnostics-gutter-ui-gutter-action', hidden: '' };const editorToMarkers = new WeakMap();const itemToEditor = new WeakMap();function applyUpdateToEditor(editor, update, diagnosticUpdater) {let gutter = editor.gutterWithName(GUTTER_ID);if (!gutter) {// TODO(jessicalin): Determine an appropriate priority so that the gutter: // (1) Shows up to the right of the line numbers. // (2) Shows the items that are added to it right away. // Using a value of 10 fixes (1), but breaks (2). This seems like it is likely a bug in Atom. - // By default, a gutter will be destroyed when its editor is destroyed, // so there is no need to register a callback via onDidDestroy(). - gutter = editor.addGutter({ - name: GUTTER_ID, - visible: false, - // Priority is -200 by default and 0 is the line number - priority: -1000, - }); - } - - let marker; - let markers = editorToMarkers.get(editor); - - // TODO: Consider a more efficient strategy that does not blindly destroy all of the + gutter = editor.addGutter({ name: GUTTER_ID, visible: false, // Priority is -200 by default and 0 is the line number + priority: -1000 });}let marker;let markers = editorToMarkers.get(editor); // TODO: Consider a more efficient strategy that does not blindly destroy all of the // existing markers. - if (markers) { - for (marker of markers) { - marker.destroy(); + if (markers) {for (marker of markers) {marker.destroy(); } markers.clear(); } else { markers = new Set(); } - const rowToMessage: Map> = new Map(); - function addMessageForRow(message: DiagnosticMessage, row: number) { + const rowToMessage = new Map(); + function addMessageForRow(message, row) { let messages = rowToMessage.get(row); if (!messages) { messages = []; @@ -114,15 +114,15 @@ export function applyUpdateToEditor( for (const message of update.messages) { const wordRange = - message.range != null && message.range.isEmpty() - ? wordAtPosition(editor, message.range.start) - : null; + message.range != null && message.range.isEmpty() ? + (0, (_range || _load_range()).wordAtPosition)(editor, message.range.start) : + null; const range = wordRange != null ? wordRange.range : message.range; - const highlightCssClass = classnames( - HIGHLIGHT_CSS, - HIGHLIGHT_CSS_LEVELS[message.type], - ); + const highlightCssClass = (0, (_classnames || _load_classnames()).default)( + HIGHLIGHT_CSS, + HIGHLIGHT_CSS_LEVELS[message.type]); + let highlightMarker; if (range) { @@ -142,8 +142,8 @@ export function applyUpdateToEditor( let start; let end; const lineText = editor.getTextInBufferRange( - new Range([line, 0], [line + 1, 0]), - ); + new _atom.Range([line, 0], [line + 1, 0])); + if (line === range.start.row) { start = range.start.column; @@ -161,12 +161,12 @@ export function applyUpdateToEditor( } highlightMarker = editor.markBufferRange( - new Range([line, start], [line, end]), - ); + new _atom.Range([line, start], [line, end])); + editor.decorateMarker(highlightMarker, { type: 'highlight', - class: highlightCssClass, - }); + class: highlightCssClass }); + markers.add(highlightMarker); } } else { @@ -177,14 +177,14 @@ export function applyUpdateToEditor( // Find all of the gutter markers for the same row and combine them into one marker/popup. for (const [row, messages] of rowToMessage.entries()) { // This marker adds some UI to the gutter. - const {item, dispose} = createGutterItem( - messages, - diagnosticUpdater, - gutter, - ); + const { item, dispose } = createGutterItem( + messages, + diagnosticUpdater, + gutter); + itemToEditor.set(item, editor); const gutterMarker = editor.markBufferPosition([row, 0]); - gutter.decorateMarker(gutterMarker, {item}); + gutter.decorateMarker(gutterMarker, { item }); gutterMarker.onDidDestroy(dispose); markers.add(gutterMarker); } @@ -195,19 +195,19 @@ export function applyUpdateToEditor( // TextEditor. if (update.messages.length > 0) { gutter.show(); - analytics.track('diagnostics-show-editor-diagnostics'); + (_analytics || _load_analytics()).default.track('diagnostics-show-editor-diagnostics'); } } function createGutterItem( - messages: Array, - diagnosticUpdater: DiagnosticUpdater, - gutter: atom$Gutter, -): {item: HTMLElement, dispose: () => void} { +messages, +diagnosticUpdater, +gutter) +{ // Determine which group to display. const messageGroups = new Set(); - messages.forEach(msg => messageGroups.add(GroupUtils.getGroup(msg))); - const group = GroupUtils.getHighestPriorityGroup(messageGroups); + messages.forEach(msg => messageGroups.add((_GroupUtils || _load_GroupUtils()).getGroup(msg))); + const group = (_GroupUtils || _load_GroupUtils()).getHighestPriorityGroup(messageGroups); const item = document.createElement('span'); const groupClassName = GUTTER_CSS_GROUPS[group]; @@ -215,74 +215,74 @@ function createGutterItem( // Add the icon const icon = document.createElement('span'); - icon.className = `icon icon-${GroupUtils.getIcon(group)}`; + icon.className = `icon icon-${(_GroupUtils || _load_GroupUtils()).getIcon(group)}`; item.appendChild(icon); - const spawnPopup = (): Observable => { - return Observable.create(observer => { - const goToLocation = (path: string, line: number) => { + const spawnPopup = () => { + return _rxjsBundlesRxMinJs.Observable.create(observer => { + const goToLocation = (path, line) => { // Before we jump to the location, we want to close the popup. const column = 0; - atomGoToLocation(path, {line, column}); + (0, (_goToLocation || _load_goToLocation()).goToLocation)(path, { line, column }); observer.complete(); }; const popupElement = showPopupFor( - messages, - item, - goToLocation, - diagnosticUpdater, - gutter, - ); + messages, + item, + goToLocation, + diagnosticUpdater, + gutter); + observer.next(popupElement); return () => { - ReactDOM.unmountComponentAtNode(popupElement); - invariant(popupElement.parentNode != null); + _reactDom.default.unmountComponentAtNode(popupElement);if (!( + popupElement.parentNode != null)) {throw new Error('Invariant violation: "popupElement.parentNode != null"');} popupElement.parentNode.removeChild(popupElement); }; }); }; - const hoverSubscription = Observable.fromEvent(item, 'mouseenter') - .exhaustMap((event: MouseEvent) => { - return spawnPopup() - .let( - completingSwitchMap((popupElement: HTMLElement) => { - const innerPopupElement = popupElement.firstChild; - invariant(innerPopupElement instanceof HTMLElement); - - // Events which should cause the popup to close. - return Observable.merge( - hoveringOrAiming(item, innerPopupElement), - // This makes sure that the popup disappears when you ctrl+tab to switch tabs. - observableFromSubscribeFunction(cb => - atom.workspace.onDidChangeActivePaneItem(cb), - ).mapTo(false), - ); - }), - ) - .takeWhile(Boolean); - }) - .subscribe(); + const hoverSubscription = _rxjsBundlesRxMinJs.Observable.fromEvent(item, 'mouseenter'). + exhaustMap(event => { + return spawnPopup(). + let( + (0, (_observable || _load_observable()).completingSwitchMap)(popupElement => { + const innerPopupElement = popupElement.firstChild;if (!( + innerPopupElement instanceof HTMLElement)) {throw new Error('Invariant violation: "innerPopupElement instanceof HTMLElement"');} + + // Events which should cause the popup to close. + return _rxjsBundlesRxMinJs.Observable.merge( + (0, (_aim || _load_aim()).hoveringOrAiming)(item, innerPopupElement), + // This makes sure that the popup disappears when you ctrl+tab to switch tabs. + (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => + atom.workspace.onDidChangeActivePaneItem(cb)). + mapTo(false)); + + })). + + takeWhile(Boolean); + }). + subscribe(); const dispose = () => hoverSubscription.unsubscribe(); - return {item, dispose}; + return { item, dispose }; } /** - * Shows a popup for the diagnostic just below the specified item. - */ + * Shows a popup for the diagnostic just below the specified item. + */ function showPopupFor( - messages: Array, - item: HTMLElement, - goToLocation: (filePath: NuclideUri, line: number) => mixed, - diagnosticUpdater: DiagnosticUpdater, - gutter: atom$Gutter, -): HTMLElement { +messages, +item, +goToLocation, +diagnosticUpdater, +gutter) +{ // The popup will be an absolutely positioned child element of so that it appears // on top of everything. - const workspaceElement = atom.views.getView((atom.workspace: Object)); + const workspaceElement = atom.views.getView(atom.workspace); const hostElement = document.createElement('div'); hostElement.classList.add('diagnostics-gutter-popup'); // $FlowFixMe check parentNode for null @@ -291,50 +291,50 @@ function showPopupFor( const { bottom: itemBottom, top: itemTop, - height: itemHeight, - } = item.getBoundingClientRect(); + height: itemHeight } = + item.getBoundingClientRect(); // $FlowFixMe atom$Gutter.getElement is not a documented API, but it beats using a query selector. const gutterContainer = gutter.getElement(); - const {right: gutterRight} = gutterContainer.getBoundingClientRect(); + const { right: gutterRight } = gutterContainer.getBoundingClientRect(); const trackedFixer = (...args) => { diagnosticUpdater.applyFix(...args); - analytics.track('diagnostics-gutter-autofix'); + (_analytics || _load_analytics()).default.track('diagnostics-gutter-autofix'); }; - const trackedGoToLocation = (filePath: NuclideUri, line: number) => { + const trackedGoToLocation = (filePath, line) => { goToLocation(filePath, line); - analytics.track('diagnostics-gutter-goto-location'); + (_analytics || _load_analytics()).default.track('diagnostics-gutter-goto-location'); }; - const editor = itemToEditor.get(item); - invariant(editor != null); + const editor = itemToEditor.get(item);if (!( + editor != null)) {throw new Error('Invariant violation: "editor != null"');} diagnosticUpdater.fetchCodeActions(editor, messages); const popupTop = itemBottom; - const BoundPopup = bindObservableAsProps( - observableFromSubscribeFunction(cb => - diagnosticUpdater.observeCodeActionsForMessage(cb), - ).map(codeActionsForMessage => ({ - style: {left: gutterRight, top: popupTop, position: 'absolute'}, - messages, - fixer: trackedFixer, - goToLocation: trackedGoToLocation, - codeActionsForMessage, - })), - DiagnosticsPopup, - ); - ReactDOM.render(, hostElement); + const BoundPopup = (0, (_bindObservableAsProps || _load_bindObservableAsProps()).bindObservableAsProps)( + (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => + diagnosticUpdater.observeCodeActionsForMessage(cb)). + map(codeActionsForMessage => ({ + style: { left: gutterRight, top: popupTop, position: 'absolute' }, + messages, + fixer: trackedFixer, + goToLocation: trackedGoToLocation, + codeActionsForMessage })), (_DiagnosticsPopup || _load_DiagnosticsPopup()).DiagnosticsPopup); + + + + _reactDom.default.render(_react.createElement(BoundPopup, null), hostElement); // Check to see whether the popup is within the bounds of the TextEditor. If not, display it above // the glyph rather than below it. const editorElement = atom.views.getView(editor); const { top: editorTop, - height: editorHeight, - } = editorElement.getBoundingClientRect(); + height: editorHeight } = + editorElement.getBoundingClientRect(); - const popupElement = hostElement.firstElementChild; - invariant(popupElement instanceof HTMLElement); + const popupElement = hostElement.firstElementChild;if (!( + popupElement instanceof HTMLElement)) {throw new Error('Invariant violation: "popupElement instanceof HTMLElement"');} const popupHeight = popupElement.clientHeight; if (itemTop + itemHeight + popupHeight > editorTop + editorHeight) { popupElement.style.top = `${popupTop - popupHeight - itemHeight}px`; @@ -344,11 +344,11 @@ function showPopupFor( return hostElement; } finally { messages.forEach(message => { - analytics.track('diagnostics-gutter-show-popup', { + (_analytics || _load_analytics()).default.track('diagnostics-gutter-show-popup', { 'diagnostics-provider': message.providerName, // flowlint-next-line sketchy-null-string:off - 'diagnostics-message': message.text || message.html || '', - }); + 'diagnostics-message': message.text || message.html || '' }); + }); } -} +} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/main.js b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/main.js index 65643581..ae0ef5a4 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/main.js +++ b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/main.js @@ -1,162 +1,162 @@ -/** - * 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 - * @format - */ - -import type { - DatatipProvider, - DatatipService, -} from '../../atom-ide-datatip/lib/types'; - -import type { - DiagnosticMessage, - DiagnosticMessages, - DiagnosticUpdater, -} from '../../atom-ide-diagnostics/lib/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {GlobalViewState} from './types'; - -import invariant from 'assert'; - -import analytics from 'nuclide-commons/analytics'; - -import idx from 'idx'; -import {areSetsEqual} from 'nuclide-commons/collection'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {fastDebounce} from 'nuclide-commons/observable'; -import KeyboardShortcuts from './KeyboardShortcuts'; -import Model from 'nuclide-commons/Model'; -import createPackage from 'nuclide-commons-atom/createPackage'; -import {observeTextEditors} from 'nuclide-commons-atom/text-editor'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import {DiagnosticsViewModel, WORKSPACE_VIEW_URI} from './DiagnosticsViewModel'; -import StatusBarTile from './ui/StatusBarTile'; -import {applyUpdateToEditor} from './gutter'; -import getDiagnosticDatatip from './getDiagnosticDatatip'; -import {goToLocation} from 'nuclide-commons-atom/go-to-location'; -import featureConfig from 'nuclide-commons-atom/feature-config'; -import {destroyItemWhere} from 'nuclide-commons-atom/destroyItemWhere'; -import {isValidTextEditor} from 'nuclide-commons-atom/text-editor'; -import {Observable} from 'rxjs'; -import showActionsMenu from './showActionsMenu'; -import showAtomLinterWarning from './showAtomLinterWarning'; - -const MAX_OPEN_ALL_FILES = 20; -const SHOW_TRACES_SETTING = 'atom-ide-diagnostics-ui.showDiagnosticTraces'; - -type ActivationState = {| - filterByActiveTextEditor: boolean, -|}; - -type DiagnosticsState = {| - ...ActivationState, - diagnosticUpdater: ?DiagnosticUpdater, -|}; +'use strict';var _analytics; + + + + + + + + + + + + + + + + + + + + + + + + + + +function _load_analytics() {return _analytics = _interopRequireDefault(require('nuclide-commons/analytics'));}var _idx; + +function _load_idx() {return _idx = _interopRequireDefault(require('idx'));}var _collection; +function _load_collection() {return _collection = require('nuclide-commons/collection');}var _nuclideUri; +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));}var _observable; +function _load_observable() {return _observable = require('nuclide-commons/observable');}var _KeyboardShortcuts; +function _load_KeyboardShortcuts() {return _KeyboardShortcuts = _interopRequireDefault(require('./KeyboardShortcuts'));}var _Model; +function _load_Model() {return _Model = _interopRequireDefault(require('nuclide-commons/Model'));}var _createPackage; +function _load_createPackage() {return _createPackage = _interopRequireDefault(require('nuclide-commons-atom/createPackage'));}var _textEditor; +function _load_textEditor() {return _textEditor = require('nuclide-commons-atom/text-editor');}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _event; +function _load_event() {return _event = require('nuclide-commons/event');}var _DiagnosticsViewModel; +function _load_DiagnosticsViewModel() {return _DiagnosticsViewModel = require('./DiagnosticsViewModel');}var _StatusBarTile; +function _load_StatusBarTile() {return _StatusBarTile = _interopRequireDefault(require('./ui/StatusBarTile'));}var _gutter; +function _load_gutter() {return _gutter = require('./gutter');}var _getDiagnosticDatatip; +function _load_getDiagnosticDatatip() {return _getDiagnosticDatatip = _interopRequireDefault(require('./getDiagnosticDatatip'));}var _goToLocation; +function _load_goToLocation() {return _goToLocation = require('nuclide-commons-atom/go-to-location');}var _featureConfig; +function _load_featureConfig() {return _featureConfig = _interopRequireDefault(require('nuclide-commons-atom/feature-config'));}var _destroyItemWhere; +function _load_destroyItemWhere() {return _destroyItemWhere = require('nuclide-commons-atom/destroyItemWhere');} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _showActionsMenu; +function _load_showActionsMenu() {return _showActionsMenu = _interopRequireDefault(require('./showActionsMenu'));}var _showAtomLinterWarning; +function _load_showAtomLinterWarning() {return _showAtomLinterWarning = _interopRequireDefault(require('./showAtomLinterWarning'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +const MAX_OPEN_ALL_FILES = 20; /** + * 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. + * + * + * @format + */const SHOW_TRACES_SETTING = 'atom-ide-diagnostics-ui.showDiagnosticTraces'; class Activation { - _subscriptions: UniversalDisposable; - _model: Model; - _statusBarTile: ?StatusBarTile; - _fileDiagnostics: WeakMap>; - _globalViewStates: ?Observable; - - constructor(state: ?Object): void { - this._subscriptions = new UniversalDisposable( - this.registerOpenerAndCommand(), - this._registerActionsMenu(), - showAtomLinterWarning(), - ); - this._model = new Model({ + + + + + + + constructor(state) {var _ref; + this._subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default( + this.registerOpenerAndCommand(), + this._registerActionsMenu(), + (0, (_showAtomLinterWarning || _load_showAtomLinterWarning()).default)()); + + this._model = new (_Model || _load_Model()).default({ filterByActiveTextEditor: - idx(state, _ => _.filterByActiveTextEditor) === true, - diagnosticUpdater: null, - }); + ((_ref = state) != null ? _ref.filterByActiveTextEditor : _ref) === true, + diagnosticUpdater: null }); + this._fileDiagnostics = new WeakMap(); } - consumeDatatipService(service: DatatipService): IDisposable { - const datatipProvider: DatatipProvider = { + consumeDatatipService(service) { + const datatipProvider = { // show this datatip for every type of file providerName: 'diagnostics-datatip', // Diagnostic datatips should have higher priority than most other datatips. priority: 10, datatip: (editor, position) => { const messagesAtPosition = this._getMessagesAtPosition( - editor, - position, - ); - const {diagnosticUpdater} = this._model.state; + editor, + position); + + const { diagnosticUpdater } = this._model.state; if (messagesAtPosition.length === 0 || diagnosticUpdater == null) { return Promise.resolve(null); } - return getDiagnosticDatatip( - editor, - position, - messagesAtPosition, - diagnosticUpdater, - ); - }, - }; + return (0, (_getDiagnosticDatatip || _load_getDiagnosticDatatip()).default)( + editor, + position, + messagesAtPosition, + diagnosticUpdater); + + } }; + const disposable = service.addProvider(datatipProvider); this._subscriptions.add(disposable); return disposable; } - consumeDiagnosticUpdates(diagnosticUpdater: DiagnosticUpdater): IDisposable { + consumeDiagnosticUpdates(diagnosticUpdater) { this._getStatusBarTile().consumeDiagnosticUpdates(diagnosticUpdater); this._subscriptions.add(gutterConsumeDiagnosticUpdates(diagnosticUpdater)); // Currently, the DiagnosticsView is designed to work with only one DiagnosticUpdater. if (this._model.state.diagnosticUpdater != null) { - return new UniversalDisposable(); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - this._model.setState({diagnosticUpdater}); + this._model.setState({ diagnosticUpdater }); const atomCommandsDisposable = addAtomCommands(diagnosticUpdater); this._subscriptions.add(atomCommandsDisposable); this._subscriptions.add( - // Track diagnostics for all active editors. - observeTextEditors((editor: TextEditor) => { - this._fileDiagnostics.set(editor, []); - // TODO: this is actually inefficient - this filters all file events - // by their path, so this is actually O(N^2) in the number of editors. - // We should merge the store and UI packages to get direct access. - const subscription = getEditorDiagnosticUpdates( - editor, - diagnosticUpdater, - ) - .finally(() => { - this._subscriptions.remove(subscription); - this._fileDiagnostics.delete(editor); - }) - .subscribe(update => { - this._fileDiagnostics.set(editor, update.messages); - }); - this._subscriptions.add(subscription); - }), - ); - return new UniversalDisposable(atomCommandsDisposable, () => { - invariant(this._model.state.diagnosticUpdater === diagnosticUpdater); - this._model.setState({diagnosticUpdater: null}); + // Track diagnostics for all active editors. + (0, (_textEditor || _load_textEditor()).observeTextEditors)(editor => { + this._fileDiagnostics.set(editor, []); + // TODO: this is actually inefficient - this filters all file events + // by their path, so this is actually O(N^2) in the number of editors. + // We should merge the store and UI packages to get direct access. + const subscription = getEditorDiagnosticUpdates( + editor, + diagnosticUpdater). + + finally(() => { + this._subscriptions.remove(subscription); + this._fileDiagnostics.delete(editor); + }). + subscribe(update => { + this._fileDiagnostics.set(editor, update.messages); + }); + this._subscriptions.add(subscription); + })); + + return new (_UniversalDisposable || _load_UniversalDisposable()).default(atomCommandsDisposable, () => {if (!( + this._model.state.diagnosticUpdater === diagnosticUpdater)) {throw new Error('Invariant violation: "this._model.state.diagnosticUpdater === diagnosticUpdater"');} + this._model.setState({ diagnosticUpdater: null }); }); } - consumeStatusBar(statusBar: atom$StatusBar): void { + consumeStatusBar(statusBar) { this._getStatusBarTile().consumeStatusBar(statusBar); } - deserializeDiagnosticsViewModel(): DiagnosticsViewModel { + deserializeDiagnosticsViewModel() { return this._createDiagnosticsViewModel(); } - dispose(): void { + dispose() { this._subscriptions.dispose(); if (this._statusBarTile) { this._statusBarTile.dispose(); @@ -164,220 +164,220 @@ class Activation { } } - serialize(): ActivationState { - const {filterByActiveTextEditor} = this._model.state; + serialize() { + const { filterByActiveTextEditor } = this._model.state; return { - filterByActiveTextEditor, - }; + filterByActiveTextEditor }; + } - _createDiagnosticsViewModel(): DiagnosticsViewModel { - return new DiagnosticsViewModel(this._getGlobalViewStates()); + _createDiagnosticsViewModel() { + return new (_DiagnosticsViewModel || _load_DiagnosticsViewModel()).DiagnosticsViewModel(this._getGlobalViewStates()); } /** - * An observable of the state that's shared between all panel copies. State that's unique to a - * single copy of the diagnostics panel is managed in DiagnosticsViewModel. Generally, users will - * only have one copy of the diagnostics panel so this is mostly a theoretical distinction, - * however, each copy should have its own sorting, filtering, etc. - */ - _getGlobalViewStates(): Observable { + * An observable of the state that's shared between all panel copies. State that's unique to a + * single copy of the diagnostics panel is managed in DiagnosticsViewModel. Generally, users will + * only have one copy of the diagnostics panel so this is mostly a theoretical distinction, + * however, each copy should have its own sorting, filtering, etc. + */ + _getGlobalViewStates() { if (this._globalViewStates == null) { const packageStates = this._model.toObservable(); - const updaters = packageStates - .map(state => state.diagnosticUpdater) - .distinctUntilChanged(); - - const diagnosticsStream = updaters - .switchMap( - updater => - updater == null - ? Observable.of([]) - : observableFromSubscribeFunction(updater.observeMessages), - ) - .map(diagnostics => diagnostics.filter(d => d.type !== 'Hint')) - .let(fastDebounce(100)) - .startWith([]); - - const showTracesStream: Observable< - boolean, - > = (featureConfig.observeAsStream(SHOW_TRACES_SETTING): any); + const updaters = packageStates. + map(state => state.diagnosticUpdater). + distinctUntilChanged(); + + const diagnosticsStream = updaters. + switchMap( + updater => + updater == null ? + _rxjsBundlesRxMinJs.Observable.of([]) : + (0, (_event || _load_event()).observableFromSubscribeFunction)(updater.observeMessages)). + + map(diagnostics => diagnostics.filter(d => d.type !== 'Hint')). + let((0, (_observable || _load_observable()).fastDebounce)(100)). + startWith([]); + + const showTracesStream = + + (_featureConfig || _load_featureConfig()).default.observeAsStream(SHOW_TRACES_SETTING); const setShowTraces = showTraces => { - featureConfig.set(SHOW_TRACES_SETTING, showTraces); + (_featureConfig || _load_featureConfig()).default.set(SHOW_TRACES_SETTING, showTraces); }; - const showDirectoryColumnStream: Observable< - boolean, - > = (featureConfig.observeAsStream( - 'atom-ide-diagnostics-ui.showDirectoryColumn', - ): any); + const showDirectoryColumnStream = + + (_featureConfig || _load_featureConfig()).default.observeAsStream( + 'atom-ide-diagnostics-ui.showDirectoryColumn'); + + + const autoVisibilityStream = + + (_featureConfig || _load_featureConfig()).default.observeAsStream( + 'atom-ide-diagnostics-ui.autoVisibility'); - const autoVisibilityStream: Observable< - boolean, - > = (featureConfig.observeAsStream( - 'atom-ide-diagnostics-ui.autoVisibility', - ): any); const pathToActiveTextEditorStream = getActiveEditorPaths(); - const filterByActiveTextEditorStream = packageStates - .map(state => state.filterByActiveTextEditor) - .distinctUntilChanged(); + const filterByActiveTextEditorStream = packageStates. + map(state => state.filterByActiveTextEditor). + distinctUntilChanged(); const setFilterByActiveTextEditor = filterByActiveTextEditor => { - this._model.setState({filterByActiveTextEditor}); + this._model.setState({ filterByActiveTextEditor }); }; - const supportedMessageKindsStream = updaters - .switchMap( - updater => - updater == null - ? Observable.of(new Set(['lint'])) - : observableFromSubscribeFunction( - updater.observeSupportedMessageKinds.bind(updater), - ), - ) - .distinctUntilChanged(areSetsEqual); + const supportedMessageKindsStream = updaters. + switchMap( + updater => + updater == null ? + _rxjsBundlesRxMinJs.Observable.of(new Set(['lint'])) : + (0, (_event || _load_event()).observableFromSubscribeFunction)( + updater.observeSupportedMessageKinds.bind(updater))). + + + distinctUntilChanged((_collection || _load_collection()).areSetsEqual); const uiConfigStream = updaters.switchMap( - updater => - updater == null - ? Observable.of([]) - : observableFromSubscribeFunction( - updater.observeUiConfig.bind(updater), - ), - ); - - this._globalViewStates = Observable.combineLatest( - diagnosticsStream, - filterByActiveTextEditorStream, - pathToActiveTextEditorStream, - showTracesStream, - showDirectoryColumnStream, - autoVisibilityStream, - supportedMessageKindsStream, - uiConfigStream, - // $FlowFixMe - ( - diagnostics, - filterByActiveTextEditor, - pathToActiveTextEditor, - showTraces, - showDirectoryColumn, - autoVisibility, - supportedMessageKinds, - uiConfig, - ) => ({ - diagnostics, - filterByActiveTextEditor, - pathToActiveTextEditor, - showTraces, - showDirectoryColumn, - autoVisibility, - onShowTracesChange: setShowTraces, - onFilterByActiveTextEditorChange: setFilterByActiveTextEditor, - supportedMessageKinds, - uiConfig, - }), - ); + updater => + updater == null ? + _rxjsBundlesRxMinJs.Observable.of([]) : + (0, (_event || _load_event()).observableFromSubscribeFunction)( + updater.observeUiConfig.bind(updater))); + + + + this._globalViewStates = _rxjsBundlesRxMinJs.Observable.combineLatest( + diagnosticsStream, + filterByActiveTextEditorStream, + pathToActiveTextEditorStream, + showTracesStream, + showDirectoryColumnStream, + autoVisibilityStream, + supportedMessageKindsStream, + uiConfigStream, + // $FlowFixMe + ( + diagnostics, + filterByActiveTextEditor, + pathToActiveTextEditor, + showTraces, + showDirectoryColumn, + autoVisibility, + supportedMessageKinds, + uiConfig) => ( + { + diagnostics, + filterByActiveTextEditor, + pathToActiveTextEditor, + showTraces, + showDirectoryColumn, + autoVisibility, + onShowTracesChange: setShowTraces, + onFilterByActiveTextEditorChange: setFilterByActiveTextEditor, + supportedMessageKinds, + uiConfig })); + + } return this._globalViewStates; } - registerOpenerAndCommand(): IDisposable { + registerOpenerAndCommand() { const commandDisposable = atom.commands.add( - 'atom-workspace', - 'diagnostics:toggle-table', - () => { - atom.workspace.toggle(WORKSPACE_VIEW_URI); - }, - ); - return new UniversalDisposable( - atom.workspace.addOpener(uri => { - if (uri === WORKSPACE_VIEW_URI) { - return this._createDiagnosticsViewModel(); - } - }), - () => { - destroyItemWhere(item => item instanceof DiagnosticsViewModel); - }, - commandDisposable, - ); + 'atom-workspace', + 'diagnostics:toggle-table', + () => { + atom.workspace.toggle((_DiagnosticsViewModel || _load_DiagnosticsViewModel()).WORKSPACE_VIEW_URI); + }); + + return new (_UniversalDisposable || _load_UniversalDisposable()).default( + atom.workspace.addOpener(uri => { + if (uri === (_DiagnosticsViewModel || _load_DiagnosticsViewModel()).WORKSPACE_VIEW_URI) { + return this._createDiagnosticsViewModel(); + } + }), + () => { + (0, (_destroyItemWhere || _load_destroyItemWhere()).destroyItemWhere)(item => item instanceof (_DiagnosticsViewModel || _load_DiagnosticsViewModel()).DiagnosticsViewModel); + }, + commandDisposable); + } - _registerActionsMenu(): IDisposable { + _registerActionsMenu() { return atom.commands.add( - 'atom-text-editor', - 'diagnostics:show-actions-at-position', - () => { - const editor = atom.workspace.getActiveTextEditor(); - const {diagnosticUpdater} = this._model.state; - if (editor == null || diagnosticUpdater == null) { - return; - } - const position = editor.getCursorBufferPosition(); - const messagesAtPosition = this._getMessagesAtPosition( - editor, - position, - ); - if (messagesAtPosition.length === 0) { - return; - } - showActionsMenu( - editor, - position, - messagesAtPosition, - diagnosticUpdater, - ); - }, - ); + 'atom-text-editor', + 'diagnostics:show-actions-at-position', + () => { + const editor = atom.workspace.getActiveTextEditor(); + const { diagnosticUpdater } = this._model.state; + if (editor == null || diagnosticUpdater == null) { + return; + } + const position = editor.getCursorBufferPosition(); + const messagesAtPosition = this._getMessagesAtPosition( + editor, + position); + + if (messagesAtPosition.length === 0) { + return; + } + (0, (_showActionsMenu || _load_showActionsMenu()).default)( + editor, + position, + messagesAtPosition, + diagnosticUpdater); + + }); + } - _getStatusBarTile(): StatusBarTile { + _getStatusBarTile() { if (!this._statusBarTile) { - this._statusBarTile = new StatusBarTile(); + this._statusBarTile = new (_StatusBarTile || _load_StatusBarTile()).default(); } return this._statusBarTile; } _getMessagesAtPosition( - editor: atom$TextEditor, - position: atom$Point, - ): Array { + editor, + position) + { const messagesForFile = this._fileDiagnostics.get(editor); if (messagesForFile == null) { return []; } return messagesForFile.filter( - message => message.range != null && message.range.containsPoint(position), - ); - } -} + message => message.range != null && message.range.containsPoint(position)); + + }} + function gutterConsumeDiagnosticUpdates( - diagnosticUpdater: DiagnosticUpdater, -): IDisposable { - const subscriptions = new UniversalDisposable(); +diagnosticUpdater) +{ + const subscriptions = new (_UniversalDisposable || _load_UniversalDisposable()).default(); subscriptions.add( - observeTextEditors((editor: TextEditor) => { - const subscription = getEditorDiagnosticUpdates(editor, diagnosticUpdater) - .finally(() => { - subscriptions.remove(subscription); - }) - .subscribe(update => { - // Although the subscription should be cleaned up on editor destroy, - // the very act of destroying the editor can trigger diagnostic updates. - // Thus this callback can still be triggered after the editor is destroyed. - if (!editor.isDestroyed()) { - applyUpdateToEditor(editor, update, diagnosticUpdater); - } - }); - subscriptions.add(subscription); - }), - ); + (0, (_textEditor || _load_textEditor()).observeTextEditors)(editor => { + const subscription = getEditorDiagnosticUpdates(editor, diagnosticUpdater). + finally(() => { + subscriptions.remove(subscription); + }). + subscribe(update => { + // Although the subscription should be cleaned up on editor destroy, + // the very act of destroying the editor can trigger diagnostic updates. + // Thus this callback can still be triggered after the editor is destroyed. + if (!editor.isDestroyed()) { + (0, (_gutter || _load_gutter()).applyUpdateToEditor)(editor, update, diagnosticUpdater); + } + }); + subscriptions.add(subscription); + })); + return subscriptions; } -function addAtomCommands(diagnosticUpdater: DiagnosticUpdater): IDisposable { +function addAtomCommands(diagnosticUpdater) { const fixAllInCurrentFile = () => { const editor = atom.workspace.getActiveTextEditor(); if (editor == null) { @@ -387,52 +387,52 @@ function addAtomCommands(diagnosticUpdater: DiagnosticUpdater): IDisposable { if (path == null) { return; } - analytics.track('diagnostics-autofix-all-in-file'); + (_analytics || _load_analytics()).default.track('diagnostics-autofix-all-in-file'); diagnosticUpdater.applyFixesForFile(path); }; const openAllFilesWithErrors = () => { - analytics.track('diagnostics-panel-open-all-files-with-errors'); - observableFromSubscribeFunction(diagnosticUpdater.observeMessages) - .first() - .subscribe((messages: Array) => { - const errorsToOpen = getTopMostErrorLocationsByFilePath(messages); - - if (errorsToOpen.size > MAX_OPEN_ALL_FILES) { - atom.notifications.addError( - `Diagnostics: Will not open more than ${MAX_OPEN_ALL_FILES} files`, - ); - return; - } + (_analytics || _load_analytics()).default.track('diagnostics-panel-open-all-files-with-errors'); + (0, (_event || _load_event()).observableFromSubscribeFunction)(diagnosticUpdater.observeMessages). + first(). + subscribe(messages => { + const errorsToOpen = getTopMostErrorLocationsByFilePath(messages); - const column = 0; - errorsToOpen.forEach((line, uri) => goToLocation(uri, {line, column})); - }); + if (errorsToOpen.size > MAX_OPEN_ALL_FILES) { + atom.notifications.addError( + `Diagnostics: Will not open more than ${MAX_OPEN_ALL_FILES} files`); + + return; + } + + const column = 0; + errorsToOpen.forEach((line, uri) => (0, (_goToLocation || _load_goToLocation()).goToLocation)(uri, { line, column })); + }); }; - return new UniversalDisposable( - atom.commands.add( - 'atom-workspace', - 'diagnostics:fix-all-in-current-file', - fixAllInCurrentFile, - ), - atom.commands.add( - 'atom-workspace', - 'diagnostics:open-all-files-with-errors', - openAllFilesWithErrors, - ), - new KeyboardShortcuts(diagnosticUpdater), - ); + return new (_UniversalDisposable || _load_UniversalDisposable()).default( + atom.commands.add( + 'atom-workspace', + 'diagnostics:fix-all-in-current-file', + fixAllInCurrentFile), + + atom.commands.add( + 'atom-workspace', + 'diagnostics:open-all-files-with-errors', + openAllFilesWithErrors), + + new (_KeyboardShortcuts || _load_KeyboardShortcuts()).default(diagnosticUpdater)); + } function getTopMostErrorLocationsByFilePath( - messages: Array, -): Map { - const errorLocations: Map = new Map(); +messages) +{ + const errorLocations = new Map(); messages.forEach(message => { const filePath = message.filePath; - if (nuclideUri.endsWithSeparator(filePath)) { + if ((_nuclideUri || _load_nuclideUri()).default.endsWithSeparator(filePath)) { return; } @@ -451,58 +451,58 @@ function getTopMostErrorLocationsByFilePath( return errorLocations; } -function getActiveEditorPaths(): Observable { +function getActiveEditorPaths() { const center = atom.workspace.getCenter(); return ( - observableFromSubscribeFunction(center.observeActivePaneItem.bind(center)) - .map(paneItem => (isValidTextEditor(paneItem) ? paneItem : null)) - // We want the stream to contain the last valid text editor. Normally that means just ignoring - // non-editors, except initially, when there hasn't been an active editor yet. - .filter((paneItem, index) => paneItem != null || index === 0) - .switchMap(textEditor_ => { - const textEditor: ?atom$TextEditor = (textEditor_: any); - if (textEditor == null) { - return Observable.of(null); - } - // An observable that emits the editor path and then, when the editor's destroyed, null. - return Observable.concat( - Observable.of(textEditor.getPath()), - observableFromSubscribeFunction( - textEditor.onDidDestroy.bind(textEditor), - ) - .take(1) - .mapTo(null), - ); - }) - .distinctUntilChanged() - ); + (0, (_event || _load_event()).observableFromSubscribeFunction)(center.observeActivePaneItem.bind(center)). + map(paneItem => (0, (_textEditor || _load_textEditor()).isValidTextEditor)(paneItem) ? paneItem : null) + // We want the stream to contain the last valid text editor. Normally that means just ignoring + // non-editors, except initially, when there hasn't been an active editor yet. + .filter((paneItem, index) => paneItem != null || index === 0). + switchMap(textEditor_ => { + const textEditor = textEditor_; + if (textEditor == null) { + return _rxjsBundlesRxMinJs.Observable.of(null); + } + // An observable that emits the editor path and then, when the editor's destroyed, null. + return _rxjsBundlesRxMinJs.Observable.concat( + _rxjsBundlesRxMinJs.Observable.of(textEditor.getPath()), + (0, (_event || _load_event()).observableFromSubscribeFunction)( + textEditor.onDidDestroy.bind(textEditor)). + + take(1). + mapTo(null)); + + }). + distinctUntilChanged()); + } function getEditorDiagnosticUpdates( - editor: atom$TextEditor, - diagnosticUpdater: DiagnosticUpdater, -): Observable { - return observableFromSubscribeFunction(editor.onDidChangePath.bind(editor)) - .startWith(editor.getPath()) - .switchMap( - filePath => - filePath != null - ? observableFromSubscribeFunction(cb => - diagnosticUpdater.observeFileMessages(filePath, cb), - ) - : Observable.empty(), - ) - .map(diagnosticMessages => { - return { - ...diagnosticMessages, - messages: diagnosticMessages.messages.filter( - diagnostic => diagnostic.type !== 'Hint', - ), - }; - }) - .takeUntil( - observableFromSubscribeFunction(editor.onDidDestroy.bind(editor)), - ); +editor, +diagnosticUpdater) +{ + return (0, (_event || _load_event()).observableFromSubscribeFunction)(editor.onDidChangePath.bind(editor)). + startWith(editor.getPath()). + switchMap( + filePath => + filePath != null ? + (0, (_event || _load_event()).observableFromSubscribeFunction)(cb => + diagnosticUpdater.observeFileMessages(filePath, cb)) : + + _rxjsBundlesRxMinJs.Observable.empty()). + + map(diagnosticMessages => { + return Object.assign({}, + diagnosticMessages, { + messages: diagnosticMessages.messages.filter( + diagnostic => diagnostic.type !== 'Hint') }); + + + }). + takeUntil( + (0, (_event || _load_event()).observableFromSubscribeFunction)(editor.onDidDestroy.bind(editor))); + } -createPackage(module.exports, Activation); +(0, (_createPackage || _load_createPackage()).default)(module.exports, Activation); \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/showActionsMenu.js b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/showActionsMenu.js index 71a29dee..7c5b6b84 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/showActionsMenu.js +++ b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/showActionsMenu.js @@ -1,111 +1,111 @@ -/** - * 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 - * @format - */ - -import type { - DiagnosticUpdater, - DiagnosticMessage, -} from '../../atom-ide-diagnostics/lib/types'; - -import invariant from 'assert'; -import electron from 'electron'; -import {Observable} from 'rxjs'; -import {arrayCompact, arrayFlatten} from 'nuclide-commons/collection'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -const {remote} = electron; -invariant(remote != null); - -const CODE_ACTIONS_TIMEOUT = 2000; - -export default function showActionsMenu( - editor: TextEditor, - position: atom$Point, - messagesAtPosition: Array, - diagnosticUpdater: DiagnosticUpdater, -): IDisposable { - diagnosticUpdater.fetchCodeActions(editor, messagesAtPosition); - - return new UniversalDisposable( - observableFromSubscribeFunction(cb => - diagnosticUpdater.observeCodeActionsForMessage(cb), - ) - .filter(codeActionsForMessage => { - return messagesAtPosition.every(message => - codeActionsForMessage.has(message), - ); - }) - .take(1) - .race(Observable.of(new WeakMap()).delay(CODE_ACTIONS_TIMEOUT)) - .subscribe(codeActionsForMessage => { - const currentWindow = remote.getCurrentWindow(); - const menu = new remote.Menu(); - const fixes = arrayCompact( - messagesAtPosition.map(message => { - const {fix} = message; - if (fix == null) { - return null; - } - const fixTitle = fix.title == null ? 'Fix' : fix.title; - return { - title: `${fixTitle} (${message.providerName})`, - apply: () => diagnosticUpdater.applyFix(message), - }; - }), - ); - const actions = arrayFlatten( - messagesAtPosition.map(message => { - const codeActions = codeActionsForMessage.get(message); - if (codeActions == null) { - return []; - } - return Array.from(codeActions).map(([title, codeAction]) => ({ - title, - apply: () => codeAction.apply(), - })); - }), - ); - - [...fixes, ...actions].forEach(action => { - menu.append( - new remote.MenuItem({ - type: 'normal', - label: action.title, - click: () => { - action.apply(); - }, - }), - ); - }); - - const screenPosition = editor.screenPositionForBufferPosition(position); - const editorView = atom.views.getView(editor); - const pixelPosition = editorView.pixelPositionForScreenPosition( - screenPosition, - ); - // Pixel coordinates are relative to the editor's scroll view. - const scrollView = editorView.querySelector('.scroll-view'); - invariant(scrollView != null); - const boundingRect = scrollView.getBoundingClientRect(); - menu.popup( - currentWindow, - Math.round( - boundingRect.left + pixelPosition.left - editorView.getScrollLeft(), - ), - Math.round( - boundingRect.top + pixelPosition.top - editorView.getScrollTop(), - ), - 0, - ); - }), - ); -} +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default = + + + + + + + + + + + + + + + + + + + + + + + + + + + + +showActionsMenu;var _electron = _interopRequireDefault(require('electron'));var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _collection;function _load_collection() {return _collection = require('nuclide-commons/collection');}var _event;function _load_event() {return _event = require('nuclide-commons/event');}var _UniversalDisposable;function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}const { remote } = _electron.default; /** + * 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. + * + * + * @format + */if (!(remote != null)) {throw new Error('Invariant violation: "remote != null"');}const CODE_ACTIONS_TIMEOUT = 2000;function showActionsMenu(editor, position, messagesAtPosition, diagnosticUpdater) {diagnosticUpdater.fetchCodeActions(editor, messagesAtPosition);return new (_UniversalDisposable || _load_UniversalDisposable()).default((0, (_event || _load_event()).observableFromSubscribeFunction)(cb => diagnosticUpdater.observeCodeActionsForMessage(cb)). + + filter(codeActionsForMessage => { + return messagesAtPosition.every(message => + codeActionsForMessage.has(message)); + + }). + take(1). + race(_rxjsBundlesRxMinJs.Observable.of(new WeakMap()).delay(CODE_ACTIONS_TIMEOUT)). + subscribe(codeActionsForMessage => { + const currentWindow = remote.getCurrentWindow(); + const menu = new remote.Menu(); + const fixes = (0, (_collection || _load_collection()).arrayCompact)( + messagesAtPosition.map(message => { + const { fix } = message; + if (fix == null) { + return null; + } + const fixTitle = fix.title == null ? 'Fix' : fix.title; + return { + title: `${fixTitle} (${message.providerName})`, + apply: () => diagnosticUpdater.applyFix(message) }; + + })); + + const actions = (0, (_collection || _load_collection()).arrayFlatten)( + messagesAtPosition.map(message => { + const codeActions = codeActionsForMessage.get(message); + if (codeActions == null) { + return []; + } + return Array.from(codeActions).map(([title, codeAction]) => ({ + title, + apply: () => codeAction.apply() })); + + })); + + + [...fixes, ...actions].forEach(action => { + menu.append( + new remote.MenuItem({ + type: 'normal', + label: action.title, + click: () => { + action.apply(); + } })); + + + }); + + const screenPosition = editor.screenPositionForBufferPosition(position); + const editorView = atom.views.getView(editor); + const pixelPosition = editorView.pixelPositionForScreenPosition( + screenPosition); + + // Pixel coordinates are relative to the editor's scroll view. + const scrollView = editorView.querySelector('.scroll-view');if (!( + scrollView != null)) {throw new Error('Invariant violation: "scrollView != null"');} + const boundingRect = scrollView.getBoundingClientRect(); + menu.popup( + currentWindow, + Math.round( + boundingRect.left + pixelPosition.left - editorView.getScrollLeft()), + + Math.round( + boundingRect.top + pixelPosition.top - editorView.getScrollTop()), + + 0); + + })); + +} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/showAtomLinterWarning.js b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/showAtomLinterWarning.js index 38ec763f..78085963 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/showAtomLinterWarning.js +++ b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/showAtomLinterWarning.js @@ -1,90 +1,90 @@ -/** - * 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 - * @format - */ - -import featureConfig from 'nuclide-commons-atom/feature-config'; -import {observableFromSubscribeFunction} from 'nuclide-commons/event'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Observable} from 'rxjs'; - -const LINTER_PACKAGE = 'linter'; - -function observePackageIsEnabled(): Observable { - return Observable.merge( - Observable.of(atom.packages.isPackageActive(LINTER_PACKAGE)), - observableFromSubscribeFunction( - atom.packages.onDidActivatePackage.bind(atom.packages), - ) - .filter(pkg => pkg.name === LINTER_PACKAGE) - .mapTo(true), - observableFromSubscribeFunction( - atom.packages.onDidDeactivatePackage.bind(atom.packages), - ) - .filter(pkg => pkg.name === LINTER_PACKAGE) - .mapTo(false), - ); -} - -function disableLinter(): void { - atom.packages.disablePackage(LINTER_PACKAGE); -} - -function disableDiagnostics(): void { - featureConfig.set('use.atom-ide-diagnostics-ui', false); -} - -export default function showAtomLinterWarning(): IDisposable { - const packageName = featureConfig.getPackageName(); - return new UniversalDisposable( - observePackageIsEnabled() - .distinctUntilChanged() - .switchMap(enabled => { - if (!enabled) { - return Observable.empty(); - } - const notification = atom.notifications.addInfo('Choose a linter UI', { - description: - 'You have both `linter` and `atom-ide-diagnostics` enabled, which will both ' + - 'display lint results for Linter-based packages.\n\n' + - 'To avoid duplicate results, please disable one of the packages.' + - (packageName === 'nuclide' - ? '\n\nNote that Flow and Hack errors are not compatible with `linter`.' - : ''), - dismissable: true, - buttons: [ - { - text: 'Disable Linter', - onDidClick() { - disableLinter(); - }, - }, - { - text: 'Disable Diagnostics', - onDidClick() { - disableDiagnostics(); - atom.notifications.addInfo('Re-enabling Diagnostics', { - description: - 'To re-enable diagnostics, please enable "Diagnostics" under the "Enabled Features" ' + - `section in \`${packageName}\` settings.`, - }); - }, - }, - ], - }); - return Observable.create(() => ({ - unsubscribe() { - notification.dismiss(); - }, - })); - }) - .subscribe(), - ); -} +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +showAtomLinterWarning;var _featureConfig;function _load_featureConfig() {return _featureConfig = _interopRequireDefault(require('nuclide-commons-atom/feature-config'));}var _event;function _load_event() {return _event = require('nuclide-commons/event');}var _UniversalDisposable;function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */const LINTER_PACKAGE = 'linter';function observePackageIsEnabled() {return _rxjsBundlesRxMinJs.Observable.merge(_rxjsBundlesRxMinJs.Observable.of(atom.packages.isPackageActive(LINTER_PACKAGE)), (0, (_event || _load_event()).observableFromSubscribeFunction)(atom.packages.onDidActivatePackage.bind(atom.packages)).filter(pkg => pkg.name === LINTER_PACKAGE).mapTo(true), (0, (_event || _load_event()).observableFromSubscribeFunction)(atom.packages.onDidDeactivatePackage.bind(atom.packages)).filter(pkg => pkg.name === LINTER_PACKAGE).mapTo(false));}function disableLinter() {atom.packages.disablePackage(LINTER_PACKAGE);}function disableDiagnostics() {(_featureConfig || _load_featureConfig()).default.set('use.atom-ide-diagnostics-ui', false);}function showAtomLinterWarning() {const packageName = (_featureConfig || _load_featureConfig()).default.getPackageName();return new (_UniversalDisposable || _load_UniversalDisposable()).default(observePackageIsEnabled().distinctUntilChanged().switchMap(enabled => {if (!enabled) {return _rxjsBundlesRxMinJs.Observable.empty();}const notification = atom.notifications.addInfo('Choose a linter UI', { description: + 'You have both `linter` and `atom-ide-diagnostics` enabled, which will both ' + + 'display lint results for Linter-based packages.\n\n' + + 'To avoid duplicate results, please disable one of the packages.' + ( + packageName === 'nuclide' ? + '\n\nNote that Flow and Hack errors are not compatible with `linter`.' : + ''), + dismissable: true, + buttons: [ + { + text: 'Disable Linter', + onDidClick() { + disableLinter(); + } }, + + { + text: 'Disable Diagnostics', + onDidClick() { + disableDiagnostics(); + atom.notifications.addInfo('Re-enabling Diagnostics', { + description: + 'To re-enable diagnostics, please enable "Diagnostics" under the "Enabled Features" ' + + `section in \`${packageName}\` settings.` }); + + } }] }); + + + + return _rxjsBundlesRxMinJs.Observable.create(() => ({ + unsubscribe() { + notification.dismiss(); + } })); + + }). + subscribe()); + +} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/sortDiagnostics.js b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/sortDiagnostics.js index c5ad3aaa..f7bc9cf7 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/sortDiagnostics.js +++ b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/sortDiagnostics.js @@ -1,94 +1,94 @@ -/** - * 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 - * @format - */ - -import type {Row} from 'nuclide-commons-ui/Table'; -import type { - DiagnosticMessageKind, - DiagnosticMessageType, -} from '../../atom-ide-diagnostics/lib/types'; -import type {DisplayDiagnostic} from './ui/DiagnosticsTable'; - -import invariant from 'assert'; - -type DiagnosticsComparison = ( - a: Row, - b: Row, -) => number; - -/* - * Sorts the diagnostics according to given column and sort direction - */ -export default function sortDiagnostics( - diagnostics: Array>, - sortedColumnName: $Keys, - sortDescending: boolean, -): Array> { - const compare = SORT_FUNCTIONS[sortedColumnName]; - invariant(compare != null); - // Don't sort in place. - const sorted = diagnostics.slice().sort(compare); - // We can't just reverse the sign of the comparison function because that would maintain the +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default = + + + + + + + + + + + + + + + + + + + + + + + + + + + + +sortDiagnostics; /* + * Sorts the diagnostics according to given column and sort direction + */ /** + * 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. + * + * + * @format + */function sortDiagnostics(diagnostics, sortedColumnName, sortDescending) {const compare = SORT_FUNCTIONS[sortedColumnName];if (!(compare != null)) {throw new Error('Invariant violation: "compare != null"');} // Don't sort in place. + const sorted = diagnostics.slice().sort(compare); // We can't just reverse the sign of the comparison function because that would maintain the // ordering of "equal" items with respect to eachother. - return sortDescending ? sorted.reverse() : sorted; -} + return sortDescending ? sorted.reverse() : sorted;}const SORT_FUNCTIONS = { classification: compose( + compareClassification, + compareSource, + comparePath, + compareDescription), -const SORT_FUNCTIONS = { - classification: compose( - compareClassification, - compareSource, - comparePath, - compareDescription, - ), providerName: compose( - compareSource, - compareClassification, - compareDescription, - comparePath, - ), + compareSource, + compareClassification, + compareDescription, + comparePath), + description: compose( - compareDescription, - compareSource, - compareClassification, - comparePath, - ), + compareDescription, + compareSource, + compareClassification, + comparePath), + dir: compose( - comparePath, - compareSource, - compareClassification, - compareDescription, - ), + comparePath, + compareSource, + compareClassification, + compareDescription), + location: compose( - compareBasename, - comparePath, - compareClassification, - compareSource, - compareDescription, - ), + compareBasename, + comparePath, + compareClassification, + compareSource, + compareDescription), + line: compose( - compareBasename, - comparePath, - compareClassification, - compareSource, - compareDescription, - ), -}; + compareBasename, + comparePath, + compareClassification, + compareSource, + compareDescription) }; + + /** - * Compose comparison functions so that, when one identifies the items as equal, the subsequent - * functions are used to resolve the abiguity. - */ + * Compose comparison functions so that, when one identifies the items as equal, the subsequent + * functions are used to resolve the abiguity. + */ function compose( - ...comparisons: Array -): DiagnosticsComparison { +...comparisons) +{ return (a, b) => { for (const compare of comparisons) { const val = compare(a, b); @@ -101,27 +101,27 @@ function compose( } function compareClassification( - a: Row, - b: Row, -): number { +a, +b) +{ return ( compareClassificationKind( - a.data.classification.kind, - b.data.classification.kind, - ) || + a.data.classification.kind, + b.data.classification.kind) || + compareClassificationSeverity( - a.data.classification.severity, - b.data.classification.severity, - ) - ); + a.data.classification.severity, + b.data.classification.severity)); + + } const KIND_ORDER = ['review', 'lint']; function compareClassificationKind( - a: ?DiagnosticMessageKind, - b: ?DiagnosticMessageKind, -): number { +a, +b) +{ const aKind = a || 'lint'; const bKind = b || 'lint'; return KIND_ORDER.indexOf(aKind) - KIND_ORDER.indexOf(bKind); @@ -130,30 +130,30 @@ function compareClassificationKind( const SEVERITY_ORDER = ['Info', 'Warning', 'Error']; function compareClassificationSeverity( - a: DiagnosticMessageType, - b: DiagnosticMessageType, -): number { +a, +b) +{ return SEVERITY_ORDER.indexOf(a) - SEVERITY_ORDER.indexOf(b); } function compareSource( - a: Row, - b: Row, -): number { +a, +b) +{ return compareStrings(a.data.providerName, b.data.providerName); } function compareDescription( - a: Row, - b: Row, -): number { +a, +b) +{ return compareStrings(a.data.description.text, b.data.description.text); } function comparePath( - a: Row, - b: Row, -): number { +a, +b) +{ const aLocation = a.data.location; const bLocation = b.data.location; if (aLocation == null && bLocation == null) { @@ -170,16 +170,16 @@ function comparePath( return pathComparison; } const aLine = - aLocation.locationInFile == null ? 0 : aLocation.locationInFile.line; + aLocation.locationInFile == null ? 0 : aLocation.locationInFile.line; const bLine = - bLocation.locationInFile == null ? 0 : bLocation.locationInFile.line; + bLocation.locationInFile == null ? 0 : bLocation.locationInFile.line; return compareNumbers(aLine, bLine); } function compareBasename( - a: Row, - b: Row, -): number { +a, +b) +{ const aLocationInFile = a.data.location && a.data.location.locationInFile; const bLocationInFile = b.data.location && b.data.location.locationInFile; if (aLocationInFile == null && bLocationInFile == null) { @@ -193,14 +193,14 @@ function compareBasename( } return ( compareStrings(aLocationInFile.basename, bLocationInFile.basename) || - compareNumbers(aLocationInFile.line, bLocationInFile.line) - ); + compareNumbers(aLocationInFile.line, bLocationInFile.line)); + } -function compareStrings(a: string, b: string): number { +function compareStrings(a, b) { return a.toLowerCase().localeCompare(b.toLowerCase()); } -function compareNumbers(a: number, b: number): number { +function compareNumbers(a, b) { return a - b; -} +} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/types.js b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/types.js index b56120b0..a726efc4 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/types.js +++ b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/types.js @@ -1,40 +1 @@ -/** - * 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 - * @format - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type { - DiagnosticMessage, - DiagnosticMessageKind, - UiConfig, -} from '../../atom-ide-diagnostics/lib/types'; - -// We group diagnostics based on kind and severity. -export type DiagnosticGroup = - | 'errors' - | 'warnings' - | 'info' - | 'review' - | 'action'; - -// State that's shared between every diagnostics panel instance. -export type GlobalViewState = { - diagnostics: Array, - pathToActiveTextEditor: ?NuclideUri, - filterByActiveTextEditor: boolean, - onFilterByActiveTextEditorChange: (isChecked: boolean) => mixed, - showDirectoryColumn: boolean, - autoVisibility: boolean, - showTraces: boolean, - onShowTracesChange: (isChecked: boolean) => mixed, - supportedMessageKinds: Set, - uiConfig: UiConfig, -}; +'use strict'; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsCodeActions.js b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsCodeActions.js index 4465e985..5ef19700 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsCodeActions.js +++ b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsCodeActions.js @@ -1,64 +1,64 @@ -/** - * 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 - * @format - */ - -import type {CodeAction} from '../../../atom-ide-code-actions/lib/types'; - -import {TextEditor} from 'atom'; -import * as React from 'react'; -import {Button} from 'nuclide-commons-ui/Button'; -import {ButtonGroup} from 'nuclide-commons-ui/ButtonGroup'; - -// Maximum number of CodeActions to show for a given Diagnostic. -const MAX_CODE_ACTIONS = 4; - -export default function DiagnosticsCodeActions(props: { - codeActions: Map, -}): React.Element { - return ( -
- {Array.from(props.codeActions.entries()) - .splice(0, MAX_CODE_ACTIONS) - // TODO: (seansegal) T21130259 Display a "more" indicator when there are many CodeActions. - .map(([title, codeAction], i) => { - return ( - - - - ); - })} -
- ); +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default = + + + + + + + + + + + + + + + + + + + + + +DiagnosticsCodeActions;var _atom = require('atom');var _react = _interopRequireWildcard(require('react'));var _Button;function _load_Button() {return _Button = require('nuclide-commons-ui/Button');}var _ButtonGroup;function _load_ButtonGroup() {return _ButtonGroup = require('nuclide-commons-ui/ButtonGroup');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} // Maximum number of CodeActions to show for a given Diagnostic. +const MAX_CODE_ACTIONS = 4; /** + * 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. + * + * + * @format + */function DiagnosticsCodeActions(props) {return _react.createElement('div', { className: 'diagnostics-code-actions' }, Array.from(props.codeActions.entries()).splice(0, MAX_CODE_ACTIONS) // TODO: (seansegal) T21130259 Display a "more" indicator when there are many CodeActions. + .map(([title, codeAction], i) => {return _react.createElement((_ButtonGroup || _load_ButtonGroup()).ButtonGroup, { key: i }, _react.createElement((_Button || _load_Button()).Button, { className: 'diagnostics-code-action-button', + size: 'EXTRA_SMALL', + onClick: () => { + // TODO: (seansegal) T21130332 Display CodeAction status indicators + codeAction. + apply(). + catch(handleCodeActionFailure). + then(() => { + // Return focus to the editor after clicking. + const activeItem = atom.workspace.getActivePaneItem(); + if (activeItem && activeItem instanceof _atom.TextEditor) { + activeItem.element.focus(); + } + }); + } }, + _react.createElement('span', { className: 'inline-block' }, title))); + + + + })); + + } -function handleCodeActionFailure(error: ?Error) { +function handleCodeActionFailure(error) { atom.notifications.addWarning('Code action could not be applied', { description: error ? error.message : '', - dismissable: true, - }); -} + dismissable: true }); + +} \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsMessage.js b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsMessage.js index e8cb1d46..b1711cb6 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsMessage.js +++ b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsMessage.js @@ -1,42 +1,42 @@ -/** - * 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 - * @format - */ - -import type {DiagnosticMessage} from '../../../atom-ide-diagnostics/lib/types'; - -import * as React from 'react'; -import {Button, ButtonTypes} from 'nuclide-commons-ui/Button'; -import {ButtonGroup} from 'nuclide-commons-ui/ButtonGroup'; -import {DiagnosticsMessageText} from './DiagnosticsMessageText'; -import {DiagnosticsTraceItem} from './DiagnosticsTraceItem'; - -type DiagnosticsMessageProps = { - // these are processed in traceElements below - /* eslint-disable react/no-unused-prop-types */ - message: DiagnosticMessage, - goToLocation: (path: string, line: number) => mixed, - fixer: (message: DiagnosticMessage) => void, - children?: React.Node, - /* eslint-enable react/no-unused-prop-types */ -}; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.DiagnosticsMessageNoHeader = exports.DiagnosticsMessage = undefined; + + + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react'));var _Button; +function _load_Button() {return _Button = require('nuclide-commons-ui/Button');}var _ButtonGroup; +function _load_ButtonGroup() {return _ButtonGroup = require('nuclide-commons-ui/ButtonGroup');}var _DiagnosticsMessageText; +function _load_DiagnosticsMessageText() {return _DiagnosticsMessageText = require('./DiagnosticsMessageText');}var _DiagnosticsTraceItem; +function _load_DiagnosticsTraceItem() {return _DiagnosticsTraceItem = require('./DiagnosticsTraceItem');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} /** + * 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. + * + * + * @format + */ const PROVIDER_CLASS_NAME = { Error: 'highlight-error', Warning: 'highlight-warning', Info: 'highlight-info', - Hint: '', -}; + Hint: '' }; -function diagnosticHeader(props: DiagnosticsMessageProps) { - const {message, fixer} = props; + +function diagnosticHeader(props) { + const { message, fixer } = props; const providerClassName = PROVIDER_CLASS_NAME[message.type]; let fixButton = null; if (message.fix != null) { @@ -44,55 +44,55 @@ function diagnosticHeader(props: DiagnosticsMessageProps) { fixer(message); }; const speculative = message.fix.speculative === true; - const buttonType = speculative ? undefined : ButtonTypes.SUCCESS; - fixButton = ( - - ); + const buttonType = speculative ? undefined : (_Button || _load_Button()).ButtonTypes.SUCCESS; + fixButton = + _react.createElement((_Button || _load_Button()).Button, { buttonType: buttonType, size: 'EXTRA_SMALL', onClick: applyFix }, + // flowlint-next-line sketchy-null-string:off + message.fix.title || 'Fix'); + + } return ( -
- {fixButton} - {message.providerName} -
- ); + _react.createElement('div', { className: 'diagnostics-popup-header' }, + _react.createElement((_ButtonGroup || _load_ButtonGroup()).ButtonGroup, null, fixButton), + _react.createElement('span', { className: providerClassName }, message.providerName))); + + } -function traceElements(props: DiagnosticsMessageProps) { - const {message, goToLocation} = props; - return message.trace && message.trace.length ? ( -
- {message.trace.map((traceItem, i) => ( - - ))} -
- ) : null; +function traceElements(props) { + const { message, goToLocation } = props; + return message.trace && message.trace.length ? + _react.createElement('div', { className: 'diagnostics-popup-trace' }, + message.trace.map((traceItem, i) => + _react.createElement((_DiagnosticsTraceItem || _load_DiagnosticsTraceItem()).DiagnosticsTraceItem, { + key: i, + trace: traceItem, + goToLocation: goToLocation }))) : + + + + null; } -export const DiagnosticsMessage = (props: DiagnosticsMessageProps) => { +const DiagnosticsMessage = exports.DiagnosticsMessage = props => { return ( -
- {diagnosticHeader(props)} -
- -
- {traceElements(props)} - {props.children} -
- ); + _react.createElement('div', null, + diagnosticHeader(props), + _react.createElement('div', { className: 'diagnostics-popup-message' }, + _react.createElement((_DiagnosticsMessageText || _load_DiagnosticsMessageText()).DiagnosticsMessageText, { message: props.message })), + + traceElements(props), + props.children)); + + }; -export const DiagnosticsMessageNoHeader = (props: DiagnosticsMessageProps) => { +const DiagnosticsMessageNoHeader = exports.DiagnosticsMessageNoHeader = props => { return ( -
- - {traceElements(props)} -
- ); -}; + _react.createElement('div', null, + _react.createElement((_DiagnosticsMessageText || _load_DiagnosticsMessageText()).DiagnosticsMessageText, { message: props.message }), + traceElements(props))); + + +}; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsMessageText.js b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsMessageText.js index affbe472..a552eb01 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsMessageText.js +++ b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsMessageText.js @@ -1,74 +1,74 @@ -/** - * 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 - * @format - */ - -import invariant from 'assert'; -import * as React from 'react'; -import {shell} from 'electron'; -import createDOMPurify from 'dompurify'; - -const domPurify = createDOMPurify(); - -type DiagnosticsMessageTextProps = { - preserveNewlines?: boolean, // defaults to true - message: { - html?: string, - text?: string, - }, -}; - -type UrlOrText = - | { - isUrl: true, - url: string, - } - | { - isUrl: false, - text: string, - }; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.DiagnosticsMessageText = undefined;exports. + + + + + + + + + + + + + + + + + + + + + + + + -// Exported for testing. -export function separateUrls(message: string): Array { - // Don't match periods at the end of URLs, because those are usually just to + + + + + + + + + + + + +separateUrls = separateUrls;var _react = _interopRequireWildcard(require('react'));var _electron = require('electron');var _dompurify;function _load_dompurify() {return _dompurify = _interopRequireDefault(require('dompurify'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} /** + * 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. + * + * + * @format + */const domPurify = (0, (_dompurify || _load_dompurify()).default)(); // Exported for testing. +function separateUrls(message) {// Don't match periods at the end of URLs, because those are usually just to // end the sentence and not actually part of the URL. Optionally match // parameters following a question mark. - // first bit before query/fragment - const mainUrl = /https?:\/\/[\w/.%-]*[\w/-]/.source; - // characters allowed in query/fragment, disallow `.` at the end - const queryChars = /[\w-~%&+.!=:@/?]*[\w-~%&+!=:@/?]/.source; - const urlRegex = new RegExp( - `${mainUrl}(?:\\?${queryChars})?(?:#${queryChars})?`, - 'g', - ); - - const urls = message.match(urlRegex); - const nonUrls = message.split(urlRegex); - - const parts: Array = [ - { - isUrl: false, - text: nonUrls[0], - }, - ]; - for (let i = 1; i < nonUrls.length; i++) { - invariant(urls != null); + const mainUrl = /https?:\/\/[\w/.%-]*[\w/-]/.source; // characters allowed in query/fragment, disallow `.` at the end + const queryChars = /[\w-~%&+.!=:@/?]*[\w-~%&+!=:@/?]/.source;const urlRegex = new RegExp(`${mainUrl}(?:\\?${queryChars})?(?:#${queryChars})?`, 'g');const urls = message.match(urlRegex);const nonUrls = message.split(urlRegex); + const parts = [ + { + isUrl: false, + text: nonUrls[0] }]; + + + for (let i = 1; i < nonUrls.length; i++) {if (!( + urls != null)) {throw new Error('Invariant violation: "urls != null"');} parts.push({ isUrl: true, - url: urls[i - 1], - }); + url: urls[i - 1] }); + parts.push({ isUrl: false, - text: nonUrls[i], - }); + text: nonUrls[i] }); + } return parts; } @@ -76,56 +76,56 @@ export function separateUrls(message: string): Array { const LEADING_WHITESPACE_RE = /^\s+/; const NBSP = '\xa0'; function renderRowWithLinks( - message: string, - rowIndex: number, - rows: Array, -): React.Element { +message, +rowIndex, +rows) +{ const messageWithWhitespace = message.replace( - LEADING_WHITESPACE_RE, - whitespace => NBSP.repeat(whitespace.length), - ); + LEADING_WHITESPACE_RE, + whitespace => NBSP.repeat(whitespace.length)); + const parts = separateUrls(messageWithWhitespace).map((part, index) => { if (!part.isUrl) { return part.text; } else { const openUrl = () => { - shell.openExternal(part.url); + _electron.shell.openExternal(part.url); }; return ( - - {part.url} - - ); + _react.createElement('a', { href: '#', key: index, onClick: openUrl }, + part.url)); + + } }); return ( // We need to use a span here instead of a div so that `text-overflow: ellipsis` works. - - {parts} - {rowIndex !== rows.length - 1 &&
} -
- ); + _react.createElement('span', { key: rowIndex }, + parts, + rowIndex !== rows.length - 1 && _react.createElement('br', null))); + + } -export const DiagnosticsMessageText = (props: DiagnosticsMessageTextProps) => { - const {message} = props; +const DiagnosticsMessageText = exports.DiagnosticsMessageText = props => { + const { message } = props; if (message.html != null) { return ( - - ); + _react.createElement('span', { + title: message.text, + dangerouslySetInnerHTML: { + __html: domPurify.sanitize(message.html) } })); + + + } else if (message.text != null) { const rows = - props.preserveNewlines !== false - ? message.text.split('\n') - : [message.text]; - return {rows.map(renderRowWithLinks)}; + props.preserveNewlines !== false ? + message.text.split('\n') : + [message.text]; + return _react.createElement('span', { title: message.text }, rows.map(renderRowWithLinks)); } else { - return Diagnostic lacks message.; + return _react.createElement('span', null, 'Diagnostic lacks message.'); } -}; +}; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsPopup.js b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsPopup.js index 1401c90d..5767a37d 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsPopup.js +++ b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsPopup.js @@ -1,89 +1,89 @@ -/** - * 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 - * @format - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {DiagnosticMessage} from '../../../atom-ide-diagnostics/lib/types'; -import type {CodeAction} from '../../../atom-ide-code-actions/lib/types'; - -import * as React from 'react'; -import classnames from 'classnames'; -import analytics from 'nuclide-commons/analytics'; -import {mapUnion} from 'nuclide-commons/collection'; -import {DiagnosticsMessage} from './DiagnosticsMessage'; -import DiagnosticsCodeActions from './DiagnosticsCodeActions'; - -type DiagnosticsPopupProps = { - messages: Array, - goToLocation: (filePath: NuclideUri, line: number) => mixed, - fixer: (message: DiagnosticMessage) => void, - codeActionsForMessage?: Map>, -}; - -function renderMessage( - fixer: (message: DiagnosticMessage) => void, - goToLocation: (filePath: NuclideUri, line: number) => mixed, - codeActionsForMessage: ?Map>, - message: DiagnosticMessage, - index: number, -): React.Element { - const className = classnames( - // native-key-bindings and tabIndex=-1 are both needed to allow copying the text in the popup. - 'native-key-bindings', - 'diagnostics-popup-diagnostic', - { - 'diagnostics-popup-error': message.type === 'Error', - 'diagnostics-popup-warning': message.type === 'Warning', - 'diagnostics-popup-info': message.type === 'Info', - }, - ); +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.DiagnosticsPopup = undefined;var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + + + + + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react'));var _classnames; +function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));}var _analytics; +function _load_analytics() {return _analytics = _interopRequireDefault(require('nuclide-commons/analytics'));}var _collection; +function _load_collection() {return _collection = require('nuclide-commons/collection');}var _DiagnosticsMessage; +function _load_DiagnosticsMessage() {return _DiagnosticsMessage = require('./DiagnosticsMessage');}var _DiagnosticsCodeActions; +function _load_DiagnosticsCodeActions() {return _DiagnosticsCodeActions = _interopRequireDefault(require('./DiagnosticsCodeActions'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _objectWithoutProperties(obj, keys) {var target = {};for (var i in obj) {if (keys.indexOf(i) >= 0) continue;if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;target[i] = obj[i];}return target;} /** + * 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. + * + * + * @format + */function renderMessage(fixer, +goToLocation, +codeActionsForMessage, +message, +index) +{ + const className = (0, (_classnames || _load_classnames()).default)( + // native-key-bindings and tabIndex=-1 are both needed to allow copying the text in the popup. + 'native-key-bindings', + 'diagnostics-popup-diagnostic', + { + 'diagnostics-popup-error': message.type === 'Error', + 'diagnostics-popup-warning': message.type === 'Warning', + 'diagnostics-popup-info': message.type === 'Info' }); + + const codeActions = getCodeActions(message, codeActionsForMessage); return ( -
- - {codeActions && codeActions.size ? ( - - ) : null} - -
- ); + _react.createElement('div', { className: className, key: index, tabIndex: -1 }, + _react.createElement((_DiagnosticsMessage || _load_DiagnosticsMessage()).DiagnosticsMessage, { + fixer: fixer, + goToLocation: goToLocation, + message: message }, + codeActions && codeActions.size ? + _react.createElement((_DiagnosticsCodeActions || _load_DiagnosticsCodeActions()).default, { codeActions: codeActions }) : + null))); + + + } function getCodeActions( - message: DiagnosticMessage, - codeActionsForMessage: ?Map>, -): ?Map { +message, +codeActionsForMessage) +{ const codeActionMaps = []; if (message.actions != null && message.actions.length > 0) { codeActionMaps.push( - new Map( - message.actions.map(action => { - return [ - action.title, - { - async getTitle() { - return action.title; - }, - async apply() { - action.apply(); - }, - dispose() {}, - }, - ]; - }), - ), - ); + new Map( + message.actions.map(action => { + return [ + action.title, + { + getTitle() {return (0, _asyncToGenerator.default)(function* () { + return action.title;})(); + }, + apply() {return (0, _asyncToGenerator.default)(function* () { + action.apply();})(); + }, + dispose() {} }]; + + + }))); + + } if (codeActionsForMessage) { const actions = codeActionsForMessage.get(message); @@ -91,32 +91,31 @@ function getCodeActions( codeActionMaps.push(actions); } } - return codeActionMaps.length > 0 ? mapUnion(...codeActionMaps) : null; + return codeActionMaps.length > 0 ? (0, (_collection || _load_collection()).mapUnion)(...codeActionMaps) : null; } // TODO move LESS styles to nuclide-ui -export class DiagnosticsPopup extends React.Component { +class DiagnosticsPopup extends _react.Component { componentDidMount() { - analytics.track('diagnostics-show-popup', { + (_analytics || _load_analytics()).default.track('diagnostics-show-popup', { // Note: there could be multiple providers here (but it's less common). - providerName: this.props.messages[0].providerName, - }); + providerName: this.props.messages[0].providerName }); + } render() { - const { - fixer, - goToLocation, - codeActionsForMessage, - messages, - ...rest - } = this.props; + const _props = + + + + + + this.props,{ fixer, goToLocation, codeActionsForMessage, messages } = _props,rest = _objectWithoutProperties(_props, ['fixer', 'goToLocation', 'codeActionsForMessage', 'messages']); return ( -
- {messages.map( - renderMessage.bind(null, fixer, goToLocation, codeActionsForMessage), - )} -
- ); - } -} + _react.createElement('div', Object.assign({ className: 'diagnostics-popup' }, rest), + messages.map( + renderMessage.bind(null, fixer, goToLocation, codeActionsForMessage)))); + + + + }}exports.DiagnosticsPopup = DiagnosticsPopup; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsTable.js b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsTable.js index 1b893bd0..05754f6e 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsTable.js +++ b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsTable.js @@ -1,156 +1,156 @@ -/** - * 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 - * @format - */ - -import type { - DiagnosticMessage, - DiagnosticMessageKind, - DiagnosticMessageType, -} from '../../../atom-ide-diagnostics/lib/types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {Column, Row} from 'nuclide-commons-ui/Table'; -import type {IconName} from 'nuclide-commons-ui/Icon'; - -import classnames from 'classnames'; -import invariant from 'assert'; -import idx from 'idx'; -import memoizeUntilChanged from 'nuclide-commons/memoizeUntilChanged'; -import humanizePath from 'nuclide-commons-atom/humanizePath'; -import {insideOut, arrayEqual} from 'nuclide-commons/collection'; -import * as React from 'react'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {goToLocation} from 'nuclide-commons-atom/go-to-location'; -import {Table} from 'nuclide-commons-ui/Table'; -import sortDiagnostics from '../sortDiagnostics'; -import {DiagnosticsMessageNoHeader} from './DiagnosticsMessage'; -import {DiagnosticsMessageText} from './DiagnosticsMessageText'; -import {Icon} from 'nuclide-commons-ui/Icon'; - -const DIAGNOSTICS_TO_ROWS_TRACES_MAP = new WeakMap(); -const DIAGNOSTICS_TO_ROWS_NO_TRACES_MAP = new WeakMap(); - -// text is always used for sorting, while we render the element. -type DescriptionField = { - diagnostic: DiagnosticMessage, - showTraces: boolean, - text: string, - isPlainText: boolean, -}; - -type Location = {| - fullPath: NuclideUri, - locationInFile: ?{| - basename: string, - line: number, - |}, -|}; - -export type DisplayDiagnostic = { - +classification: { - kind: DiagnosticMessageKind, - severity: DiagnosticMessageType, - }, - +providerName: string, - +description: { - showTraces: boolean, - diagnostic: DiagnosticMessage, - text: string, - isPlainText: boolean, - }, - +dir: string, - +location: ?Location, - +line: ?number, -}; - -type ColumnName = $Keys; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _classnames; + + + + + + + + + + + + + + + + + + + + +function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));}var _idx; + +function _load_idx() {return _idx = _interopRequireDefault(require('idx'));}var _memoizeUntilChanged; +function _load_memoizeUntilChanged() {return _memoizeUntilChanged = _interopRequireDefault(require('nuclide-commons/memoizeUntilChanged'));}var _humanizePath; +function _load_humanizePath() {return _humanizePath = _interopRequireDefault(require('nuclide-commons-atom/humanizePath'));}var _collection; +function _load_collection() {return _collection = require('nuclide-commons/collection');} +var _react = _interopRequireWildcard(require('react'));var _nuclideUri; +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));}var _goToLocation; +function _load_goToLocation() {return _goToLocation = require('nuclide-commons-atom/go-to-location');}var _Table; +function _load_Table() {return _Table = require('nuclide-commons-ui/Table');}var _sortDiagnostics; +function _load_sortDiagnostics() {return _sortDiagnostics = _interopRequireDefault(require('../sortDiagnostics'));}var _DiagnosticsMessage; +function _load_DiagnosticsMessage() {return _DiagnosticsMessage = require('./DiagnosticsMessage');}var _DiagnosticsMessageText; +function _load_DiagnosticsMessageText() {return _DiagnosticsMessageText = require('./DiagnosticsMessageText');}var _Icon; +function _load_Icon() {return _Icon = require('nuclide-commons-ui/Icon');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +const DIAGNOSTICS_TO_ROWS_TRACES_MAP = new WeakMap(); /** + * 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. + * + * + * @format + */const DIAGNOSTICS_TO_ROWS_NO_TRACES_MAP = new WeakMap(); // text is always used for sorting, while we render the element. + + + + + + + + + + + + + + + + + + + + + + + + + + // Maximum number of results to render in the table before truncating and displaying a "Max results // reached" message. const MAX_RESULTS_COUNT = 1000; -type Props = { - diagnostics: Array, - selectedMessage: ?DiagnosticMessage, - gotoMessageLocation: ( - message: DiagnosticMessage, - options: {|focusEditor: boolean|}, - ) => void, - selectMessage: (message: DiagnosticMessage) => void, - showFileName: ?boolean, - showDirectoryColumn: boolean, - showTraces: boolean, -}; - -type State = { - sortDescending: boolean, - sortedColumn: ColumnName, -}; - -export default class DiagnosticsTable extends React.PureComponent< - Props, - State, -> { - _previousSelectedIndex: number = -1; - _table: ?Table; - - constructor(props: Props) { + + + + + + + + + + + + + + + + + + +class DiagnosticsTable extends _react.PureComponent + + +{ + + + + constructor(props) { super(props); // Memoize `_getRows()` - (this: any)._getRows = memoizeUntilChanged( - this._getRows, - (diagnostics, showTraces) => ({diagnostics, showTraces}), - (a, b) => - a.showTraces === b.showTraces && - arrayEqual(a.diagnostics, b.diagnostics), - ); + _initialiseProps.call(this);this._getRows = (0, (_memoizeUntilChanged || _load_memoizeUntilChanged()).default)( + this._getRows, + (diagnostics, showTraces) => ({ diagnostics, showTraces }), + (a, b) => + a.showTraces === b.showTraces && + (0, (_collection || _load_collection()).arrayEqual)(a.diagnostics, b.diagnostics)); + this.state = { sortDescending: true, - sortedColumn: 'classification', - }; + sortedColumn: 'classification' }; + } - _handleSort = (sortedColumn: ColumnName, sortDescending: boolean): void => { - this.setState({ - sortedColumn, - sortDescending, - }); - }; - - _handleSelectTableRow = ( - item: {diagnostic: DiagnosticMessage}, - index: number, - event: Event | SyntheticEvent<*>, - ): void => { - this.props.selectMessage(item.diagnostic); - // Users navigating with the keyboard may just be moving through items on their way to another. - // If they have pending pane items enabled, it's not a big deal if we open the editor anyway. - // But if they don't, we could wind up opening a ton of files they didn't even care about so, - // to be safe, we won't do anything in that case. - if ( - event.type !== 'click' && - !atom.config.get('core.allowPendingPaneItems') - ) { - return; - } - this.props.gotoMessageLocation(item.diagnostic, {focusEditor: false}); - }; - _handleConfirmTableRow = (item: {diagnostic: DiagnosticMessage}): void => { - this.props.gotoMessageLocation(item.diagnostic, {focusEditor: true}); - }; - _getColumns(): Array> { - const {showFileName, showDirectoryColumn} = this.props; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _getColumns() { + const { showFileName, showDirectoryColumn } = this.props; // These need to add up to 1. // TODO: Update the Table component so that we can have more control over this (and provide @@ -172,8 +172,8 @@ export default class DiagnosticsTable extends React.PureComponent< title: 'Path', width: DIR_WIDTH, shouldRightAlign: true, - cellClassName: 'nuclide-diagnostics-ui-cell-dir', - }); + cellClassName: 'nuclide-diagnostics-ui-cell-dir' }); + descriptionWidth -= DIR_WIDTH; } @@ -182,8 +182,8 @@ export default class DiagnosticsTable extends React.PureComponent< key: 'location', title: 'File Name', width: FILENAME_WIDTH, - cellClassName: 'nuclide-diagnostics-ui-cell-filename', - }); + cellClassName: 'nuclide-diagnostics-ui-cell-filename' }); + descriptionWidth -= FILENAME_WIDTH; } else { // Not showing the filename? Then we need a separate column for the line number. @@ -193,57 +193,57 @@ export default class DiagnosticsTable extends React.PureComponent< title: 'Line', shouldRightAlign: true, width: LINE_NUMBER_WIDTH, - minWidth: 60, - }); + minWidth: 60 }); + descriptionWidth -= LINE_NUMBER_WIDTH; } return [ - { - component: TypeComponent, - key: 'classification', - title: 'Type', - width: TYPE_WIDTH, - minWidth: 55, - cellClassName: 'nuclide-diagnostics-ui-cell-classification', - }, - { - key: 'providerName', - title: 'Source', - width: SOURCE_WIDTH, - minWidth: 100, - }, - { - component: this._renderDescription, - key: 'description', - title: 'Description', - width: descriptionWidth, - cellClassName: 'nuclide-diagnostics-ui-cell-description', - }, - ...filePathColumns, - ]; + { + component: TypeComponent, + key: 'classification', + title: 'Type', + width: TYPE_WIDTH, + minWidth: 55, + cellClassName: 'nuclide-diagnostics-ui-cell-classification' }, + + { + key: 'providerName', + title: 'Source', + width: SOURCE_WIDTH, + minWidth: 100 }, + + { + component: this._renderDescription, + key: 'description', + title: 'Description', + width: descriptionWidth, + cellClassName: 'nuclide-diagnostics-ui-cell-description' }, + + ...filePathColumns]; + } // False positive for this lint rule? // eslint-disable-next-line react/no-unused-prop-types - _renderDescription = (props: {data: DescriptionField}) => { - const {showTraces, diagnostic, text, isPlainText} = props.data; - return showTraces - ? DiagnosticsMessageNoHeader({ - message: diagnostic, - goToLocation: (file: string, line: number) => - goToLocation(file, {line}), - fixer: () => {}, - }) - : DiagnosticsMessageText({ - preserveNewlines: showTraces, - message: {text, html: isPlainText ? undefined : text}, - }); - }; + + + + + + + + + + + + + + _getSortOptions( - columns: Array>, - ): {|sortedColumn: ColumnName, sortDescending: boolean|} { + columns) + { // If the column the user sorted by has been removed, return the default sorting. We do this // (instead of updating the state) so that if the column gets added back we can return to // sorting by that. @@ -251,78 +251,78 @@ export default class DiagnosticsTable extends React.PureComponent< if (!columnKeys.includes(this.state.sortedColumn)) { return { sortedColumn: 'classification', - sortDescending: true, - }; + sortDescending: true }; + } // Otherwise, return the sorting they've chosen. return { sortedColumn: this.state.sortedColumn, - sortDescending: this.state.sortDescending, - }; + sortDescending: this.state.sortDescending }; + } - render(): React.Node { - const {diagnostics, selectedMessage, showTraces} = this.props; + render() { + const { diagnostics, selectedMessage, showTraces } = this.props; const columns = this._getColumns(); - const {sortedColumn, sortDescending} = this._getSortOptions(columns); + const { sortedColumn, sortDescending } = this._getSortOptions(columns); const diagnosticRows = this._getRows(diagnostics, showTraces); let sortedRows = this._sortRows( - diagnosticRows, - sortedColumn, - sortDescending, - ); + diagnosticRows, + sortedColumn, + sortDescending); + let maxResultsMessage; if (sortedRows.length > MAX_RESULTS_COUNT) { sortedRows = sortedRows.slice(0, MAX_RESULTS_COUNT); - maxResultsMessage = ( -
- Max results ({MAX_RESULTS_COUNT}) reached. Fix diagnostics or show - only diagnostics for the current file to view more. -
- ); + maxResultsMessage = + _react.createElement('div', { className: 'highlight-warning diagnostics-ui-table-message' }, 'Max results (', + MAX_RESULTS_COUNT, ') reached. Fix diagnostics or show only diagnostics for the current file to view more.'); + + + } const selectedIndex = this._findSelectedIndex(selectedMessage, sortedRows); return ( -
-
{ + _react.createElement('div', { + className: (0, (_classnames || _load_classnames()).default)({ + 'diagnostics-ui-table-container': true, + 'diagnostics-ui-table-container-empty': sortedRows.length === 0 }) }, + + _react.createElement((_Table || _load_Table()).Table, { + ref: table => { this._table = table; - }} - collapsable={true} - columns={columns} - emptyComponent={EmptyComponent} - fixedHeader={true} - maxBodyHeight="99999px" - rows={sortedRows} - sortable={true} - onSort={this._handleSort} - sortedColumn={sortedColumn} - sortDescending={sortDescending} - selectable={true} - selectedIndex={selectedIndex} - onSelect={this._handleSelectTableRow} - onConfirm={this._handleConfirmTableRow} - enableKeyboardNavigation={true} - /> - {maxResultsMessage} - - ); + }, + collapsable: true, + columns: columns, + emptyComponent: EmptyComponent, + fixedHeader: true, + maxBodyHeight: '99999px', + rows: sortedRows, + sortable: true, + onSort: this._handleSort, + sortedColumn: sortedColumn, + sortDescending: sortDescending, + selectable: true, + selectedIndex: selectedIndex, + onSelect: this._handleSelectTableRow, + onConfirm: this._handleConfirmTableRow, + enableKeyboardNavigation: true }), + + maxResultsMessage)); + + } - focus(): void { + focus() { if (this._table != null) { this._table.focus(); } } _findSelectedIndex( - selectedMessage: ?DiagnosticMessage, - rows: Array>, - ): number { + selectedMessage, + rows) + { if (selectedMessage == null) { return -1; } @@ -331,8 +331,8 @@ export default class DiagnosticsTable extends React.PureComponent< let bestRankedIndex = -1; // Look for the closest match, starting with the previously selected index. - for (const [row, i] of insideOut(rows, this._previousSelectedIndex)) { - const {diagnostic} = row.data.description; + for (const [row, i] of (0, (_collection || _load_collection()).insideOut)(rows, this._previousSelectedIndex)) { + const { diagnostic } = row.data.description; if (diagnostic === selectedMessage) { bestRankedIndex = i; break; @@ -353,34 +353,34 @@ export default class DiagnosticsTable extends React.PureComponent< } _getRows( - diagnostics: Array, - showTraces: boolean, - ): Array> { - const diagnosticsToRows = showTraces - ? DIAGNOSTICS_TO_ROWS_TRACES_MAP - : DIAGNOSTICS_TO_ROWS_NO_TRACES_MAP; + diagnostics, + showTraces) + { + const diagnosticsToRows = showTraces ? + DIAGNOSTICS_TO_ROWS_TRACES_MAP : + DIAGNOSTICS_TO_ROWS_NO_TRACES_MAP; return diagnostics.map(diagnostic => { let row = diagnosticsToRows.get(diagnostic); - if (row == null) { - const {dir, location} = getLocation(diagnostic); + if (row == null) {var _ref, _ref2; + const { dir, location } = getLocation(diagnostic); row = { data: { classification: { kind: diagnostic.kind || 'lint', - severity: diagnostic.type, - }, + severity: diagnostic.type }, + providerName: diagnostic.providerName, - description: { + description: Object.assign({ showTraces, - diagnostic, - ...getMessageContent(diagnostic, showTraces), - }, + diagnostic }, + getMessageContent(diagnostic, showTraces)), + dir, location, diagnostic, - line: idx(location, _ => _.locationInFile.line), - }, - }; + line: (_ref = location) != null ? (_ref2 = _ref.locationInFile) != null ? _ref2.line : _ref2 : _ref } }; + + diagnosticsToRows.set(diagnostic, row); } return row; @@ -389,35 +389,35 @@ export default class DiagnosticsTable extends React.PureComponent< // TODO: Memoize this so we don't recompute unnecessarily. _sortRows( - rows: Array>, - sortedColumn: $Keys, - descending: boolean, - ): Array> { - return sortDiagnostics(rows, sortedColumn, descending); - } -} + rows, + sortedColumn, + descending) + { + return (0, (_sortDiagnostics || _load_sortDiagnostics()).default)(rows, sortedColumn, descending); + }}exports.default = DiagnosticsTable;var _initialiseProps = function () {this._previousSelectedIndex = -1;this._handleSort = (sortedColumn, sortDescending) => {this.setState({ sortedColumn, sortDescending });};this._handleSelectTableRow = (item, index, event) => {this.props.selectMessage(item.diagnostic); // Users navigating with the keyboard may just be moving through items on their way to another. + // If they have pending pane items enabled, it's not a big deal if we open the editor anyway. + // But if they don't, we could wind up opening a ton of files they didn't even care about so, + // to be safe, we won't do anything in that case. + if (event.type !== 'click' && !atom.config.get('core.allowPendingPaneItems')) {return;}this.props.gotoMessageLocation(item.diagnostic, { focusEditor: false });};this._handleConfirmTableRow = item => {this.props.gotoMessageLocation(item.diagnostic, { focusEditor: true });};this._renderDescription = props => {const { showTraces, diagnostic, text, isPlainText } = props.data;return showTraces ? (0, (_DiagnosticsMessage || _load_DiagnosticsMessage()).DiagnosticsMessageNoHeader)({ message: diagnostic, goToLocation: (file, line) => (0, (_goToLocation || _load_goToLocation()).goToLocation)(file, { line }), fixer: () => {} }) : (0, (_DiagnosticsMessageText || _load_DiagnosticsMessageText()).DiagnosticsMessageText)({ preserveNewlines: showTraces, message: { text, html: isPlainText ? undefined : text } });};};const EmptyComponent = () => _react.createElement('div', { className: 'diagnostics-ui-empty-component' }, 'No diagnostic messages'); + -const EmptyComponent = () => ( -
No diagnostic messages
-); -type Classification = { - kind: DiagnosticMessageKind, - severity: DiagnosticMessageType, -}; -function TypeComponent(props: {data: Classification}): React.Element { + + + +function TypeComponent(props) { const classification = props.data; const iconName = getIconName(classification); - return ; + return _react.createElement((_Icon || _load_Icon()).Icon, { icon: iconName }); } -function getIconName(classification: Classification): IconName { - const {kind, severity} = classification; +function getIconName(classification) { + const { kind, severity } = classification; if (kind === 'review') { return 'nuclicon-comment-discussion'; - } - invariant(severity !== 'Hint'); + }if (!( + severity !== 'Hint')) {throw new Error('Invariant violation: "severity !== \'Hint\'"');} switch (severity) { case 'Warning': return 'nuclicon-warning'; @@ -426,22 +426,22 @@ function getIconName(classification: Classification): IconName { case 'Info': return 'info'; default: - (severity: empty); - throw new Error(`Invalid severity: ${severity}`); - } + severity; + throw new Error(`Invalid severity: ${severity}`);} + } function getMessageContent( - diagnostic: DiagnosticMessage, - showTraces: boolean, -): {text: string, isPlainText: boolean} { +diagnostic, +showTraces) +{ let text = ''; let isPlainText = true; const traces = diagnostic.trace || []; - const allMessages: Array<{html?: string, text?: string}> = [ - diagnostic, - ...traces, - ]; + const allMessages = [ + diagnostic, + ...traces]; + for (const message of allMessages) { // TODO: A mix of html and text diagnostics will yield a wonky sort ordering. if (message.html != null) { @@ -453,82 +453,82 @@ function getMessageContent( throw new Error('Neither text nor html property defined on message'); } } - return {text: text.trim(), isPlainText}; + return { text: text.trim(), isPlainText }; } -function DirComponent(props: {data: string}): React.Element { +function DirComponent(props) { return ( // We're abusing `direction: rtl` here so we need the LRM to keep the slash on the right. -
- ‎{nuclideUri.normalizeDir(props.data)}‎ -
- ); + _react.createElement('div', { className: 'nuclide-diagnostics-ui-dir-cell-contents' }, '\u200E', + (_nuclideUri || _load_nuclideUri()).default.normalizeDir(props.data), '\u200E')); + + } -function FilenameComponent(props: {data: ?Location}): React.Element { +function FilenameComponent(props) { const locationInFile = props.data && props.data.locationInFile; if (locationInFile == null) { // This is a project diagnostic. - return {DASH}; + return _react.createElement('span', null, DASH); } - const {basename, line} = locationInFile; + const { basename, line } = locationInFile; return ( - - {basename} - :{line} - - ); + _react.createElement('span', null, + basename, + _react.createElement('span', { className: 'nuclide-diagnostics-ui-line-number' }, ':', line))); + + } -function LineNumberComponent(props: {data: ?number}): React.Element { +function LineNumberComponent(props) { const line = props.data; // Show a dash if this is a project diagnostic. - return {line == null ? DASH : line}; + return _react.createElement('span', null, line == null ? DASH : line); } function getLocation( - diagnostic: DiagnosticMessage, -): {dir: string, location: ?Location} { - const {filePath, range} = diagnostic; +diagnostic) +{ + const { filePath, range } = diagnostic; const line = range ? range.start.row + 1 : 0; - const humanized = humanizePath(filePath); - if (nuclideUri.endsWithSeparator(humanized)) { + const humanized = (0, (_humanizePath || _load_humanizePath()).default)(filePath); + if ((_nuclideUri || _load_nuclideUri()).default.endsWithSeparator(humanized)) { // It's a directory. return { dir: humanized, location: { fullPath: filePath, - locationInFile: null, - }, - }; + locationInFile: null } }; + + } - const {dir, base: basename} = nuclideUri.parsePath(humanized); + const { dir, base: basename } = (_nuclideUri || _load_nuclideUri()).default.parsePath(humanized); return { dir, location: { fullPath: filePath, - locationInFile: {basename, line}, - }, - }; + locationInFile: { basename, line } } }; + + } /** - * Compute a number indicating the relative similarity of two messages. The smaller the number, the - * more similar. (`null` indicates not at all similar.) - */ -function compareMessages(a: DiagnosticMessage, b: DiagnosticMessage): ?number { + * Compute a number indicating the relative similarity of two messages. The smaller the number, the + * more similar. (`null` indicates not at all similar.) + */ +function compareMessages(a, b) { const aKind = a.kind || 'lint'; const bKind = b.kind || 'lint'; const aFilePath = a.filePath; const bFilePath = b.filePath; if ( - aKind !== bKind || - a.providerName !== b.providerName || - a.type !== b.type || - aFilePath !== bFilePath - ) { + aKind !== bKind || + a.providerName !== b.providerName || + a.type !== b.type || + aFilePath !== bFilePath) + { return null; } const aRange = a.range; @@ -549,4 +549,4 @@ function compareMessages(a: DiagnosticMessage, b: DiagnosticMessage): ?number { return Math.abs(aRange.start.row - bRange.start.row); } -const DASH = '\u2014'; +const DASH = '\u2014'; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsTraceItem.js b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsTraceItem.js index 7087e3aa..828d4273 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsTraceItem.js +++ b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsTraceItem.js @@ -1,28 +1,28 @@ -/** - * 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 - * @format - */ - -import type {DiagnosticTrace} from '../../../atom-ide-diagnostics/lib/types'; - -import * as React from 'react'; -import {DiagnosticsMessageText} from './DiagnosticsMessageText'; - -type DiagnosticsTraceItemProps = { - trace: DiagnosticTrace, - goToLocation: (path: string, line: number) => mixed, -}; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.DiagnosticsTraceItem = undefined; + + + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react'));var _DiagnosticsMessageText; +function _load_DiagnosticsMessageText() {return _DiagnosticsMessageText = require('./DiagnosticsMessageText');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} + + + + + // TODO move LESS styles to nuclide-ui -export const DiagnosticsTraceItem = (props: DiagnosticsTraceItemProps) => { - const {trace, goToLocation} = props; +const DiagnosticsTraceItem = exports.DiagnosticsTraceItem = props => { + const { trace, goToLocation } = props; let locSpan = null; // Local variable so that the type refinement holds in the onClick handler. const path = trace.filePath; @@ -33,23 +33,33 @@ export const DiagnosticsTraceItem = (props: DiagnosticsTraceItemProps) => { if (trace.range) { locString += `:${trace.range.start.row + 1}`; } - const onClick = (event: SyntheticMouseEvent<>) => { + const onClick = event => { event.stopPropagation(); goToLocation(path, Math.max(trace.range ? trace.range.start.row : 0, 0)); }; - locSpan = ( - - :{' '} - - {locString} - - - ); + locSpan = + _react.createElement('span', null, ':', + ' ', + _react.createElement('a', { href: '#', onClick: onClick }, + locString)); + + + } return ( -
- - {locSpan} -
- ); -}; + _react.createElement('div', null, + _react.createElement((_DiagnosticsMessageText || _load_DiagnosticsMessageText()).DiagnosticsMessageText, { message: trace }), + locSpan)); + + +}; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsView.js b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsView.js index a7b619e4..44b1cc7a 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsView.js +++ b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/DiagnosticsView.js @@ -1,204 +1,204 @@ -/** - * 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 - * @format - */ - -import type { - DiagnosticMessage, - DiagnosticMessageKind, - UiConfig, -} from '../../../atom-ide-diagnostics/lib/types'; -import type {DiagnosticGroup} from '../types'; -import type { - RegExpFilterChange, - RegExpFilterValue, -} from 'nuclide-commons-ui/RegExpFilter'; - -import analytics from 'nuclide-commons/analytics'; -import DiagnosticsTable from './DiagnosticsTable'; -import showModal from 'nuclide-commons-ui/showModal'; -import {Toggle} from 'nuclide-commons-ui/Toggle'; -import {Toolbar} from 'nuclide-commons-ui/Toolbar'; -import {ToolbarLeft} from 'nuclide-commons-ui/ToolbarLeft'; -import {ToolbarRight} from 'nuclide-commons-ui/ToolbarRight'; -import * as React from 'react'; -import {Button, ButtonSizes} from 'nuclide-commons-ui/Button'; -import {ButtonGroup} from 'nuclide-commons-ui/ButtonGroup'; -import FilterButton from './FilterButton'; -import RegExpFilter from 'nuclide-commons-ui/RegExpFilter'; -import SettingsModal from './SettingsModal'; - -export type Props = { - diagnostics: Array, - filterByActiveTextEditor: boolean, - onFilterByActiveTextEditorChange: (isChecked: boolean) => mixed, - showDirectoryColumn: boolean, - showTraces: boolean, - onShowTracesChange: (isChecked: boolean) => mixed, - gotoMessageLocation: ( - message: DiagnosticMessage, - options: {|focusEditor: boolean|}, - ) => void, - selectMessage: (message: DiagnosticMessage) => void, - selectedMessage: ?DiagnosticMessage, - supportedMessageKinds: Set, - uiConfig: UiConfig, - isVisible: boolean, - // Used by the DiagnosticsViewModel. - autoVisibility: boolean, // eslint-disable-line react/no-unused-prop-types - - hiddenGroups: Set, - onTypeFilterChange: (type: DiagnosticGroup) => mixed, - textFilter: RegExpFilterValue, - onTextFilterChange: (change: RegExpFilterChange) => mixed, -}; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _analytics; + + + + + + + + + + + + + + + + + + + + + + +function _load_analytics() {return _analytics = _interopRequireDefault(require('nuclide-commons/analytics'));}var _DiagnosticsTable; +function _load_DiagnosticsTable() {return _DiagnosticsTable = _interopRequireDefault(require('./DiagnosticsTable'));}var _showModal; +function _load_showModal() {return _showModal = _interopRequireDefault(require('nuclide-commons-ui/showModal'));}var _Toggle; +function _load_Toggle() {return _Toggle = require('nuclide-commons-ui/Toggle');}var _Toolbar; +function _load_Toolbar() {return _Toolbar = require('nuclide-commons-ui/Toolbar');}var _ToolbarLeft; +function _load_ToolbarLeft() {return _ToolbarLeft = require('nuclide-commons-ui/ToolbarLeft');}var _ToolbarRight; +function _load_ToolbarRight() {return _ToolbarRight = require('nuclide-commons-ui/ToolbarRight');} +var _react = _interopRequireWildcard(require('react'));var _Button; +function _load_Button() {return _Button = require('nuclide-commons-ui/Button');}var _ButtonGroup; +function _load_ButtonGroup() {return _ButtonGroup = require('nuclide-commons-ui/ButtonGroup');}var _FilterButton; +function _load_FilterButton() {return _FilterButton = _interopRequireDefault(require('./FilterButton'));}var _RegExpFilter; +function _load_RegExpFilter() {return _RegExpFilter = _interopRequireDefault(require('nuclide-commons-ui/RegExpFilter'));}var _SettingsModal; +function _load_SettingsModal() {return _SettingsModal = _interopRequireDefault(require('./SettingsModal'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + + + + + + + + + + + + + + + + + + + + + + + + + /** - * Dismissable panel that displays the diagnostics from nuclide-diagnostics-store. - */ -export default class DiagnosticsView extends React.Component { - _table: ?DiagnosticsTable; - - shouldComponentUpdate(nextProps: Props): boolean { - return nextProps.isVisible; - } - - render(): React.Element { - const {diagnostics, showDirectoryColumn, showTraces} = this.props; - - const groups = ['errors', 'warnings', 'info']; - if (this.props.supportedMessageKinds.has('review')) { - groups.push('review'); - } - if (this.props.supportedMessageKinds.has('action')) { - groups.push('action'); - } - - const showFullDescriptionToggle = diagnostics.find( - diagnostic => - // flowlint-next-line sketchy-null-string:off - diagnostic.trace || (diagnostic.text && diagnostic.text.includes('\n')), - ); - - return ( -
- - - - {groups.map(group => ( - { - this.props.onTypeFilterChange(group); - }} - /> - ))} - - - {/* TODO: This will probably change to a dropdown to also accommodate Head Changes */} - - - - {showFullDescriptionToggle ? ( - - ) : null} - -
- ); - } - - _showSettings = (): void => { - showModal(() => ); - }; - - _handleShowTracesChange = (isChecked: boolean): void => { - analytics.track('diagnostics-panel-toggle-show-traces', { - isChecked: isChecked.toString(), - }); - this.props.onShowTracesChange.call(null, isChecked); - }; - - _handleFilterByActiveTextEditorChange = (shouldFilter: boolean): void => { - analytics.track('diagnostics-panel-toggle-current-file', { - isChecked: shouldFilter.toString(), - }); - this.props.onFilterByActiveTextEditorChange.call(null, shouldFilter); - }; - - _openAllFilesWithErrors = (): void => { - atom.commands.dispatch( + * Dismissable panel that displays the diagnostics from nuclide-diagnostics-store. + */ /** + * 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. + * + * + * @format + */class DiagnosticsView extends _react.Component {constructor(...args) {var _temp;return _temp = super(...args), this. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _showSettings = () => { + (0, (_showModal || _load_showModal()).default)(() => _react.createElement((_SettingsModal || _load_SettingsModal()).default, { config: this.props.uiConfig })); + }, this. + + _handleShowTracesChange = isChecked => { + (_analytics || _load_analytics()).default.track('diagnostics-panel-toggle-show-traces', { + isChecked: isChecked.toString() }); + + this.props.onShowTracesChange.call(null, isChecked); + }, this. + + _handleFilterByActiveTextEditorChange = shouldFilter => { + (_analytics || _load_analytics()).default.track('diagnostics-panel-toggle-current-file', { + isChecked: shouldFilter.toString() }); + + this.props.onFilterByActiveTextEditorChange.call(null, shouldFilter); + }, this. + + _openAllFilesWithErrors = () => { + atom.commands.dispatch( atom.views.getView(atom.workspace), - 'diagnostics:open-all-files-with-errors', - ); - }; - - _handleFocus = (event: SyntheticMouseEvent<*>): void => { - if (this._table == null) { - return; - } - let el = event.target; - while (el != null) { - if (el.tagName === 'INPUT' || el.tagName === 'BUTTON') { + 'diagnostics:open-all-files-with-errors'); + + }, this. + + _handleFocus = event => { + if (this._table == null) { return; } - el = (el: any).parentElement; - } - this._table.focus(); - }; -} + let el = event.target; + while (el != null) { + if (el.tagName === 'INPUT' || el.tagName === 'BUTTON') { + return; + } + el = el.parentElement; + } + this._table.focus(); + }, _temp;}shouldComponentUpdate(nextProps) {return nextProps.isVisible;}render() {const { diagnostics, showDirectoryColumn, showTraces } = this.props;const groups = ['errors', 'warnings', 'info'];if (this.props.supportedMessageKinds.has('review')) {groups.push('review');}if (this.props.supportedMessageKinds.has('action')) {groups.push('action');}const showFullDescriptionToggle = diagnostics.find(diagnostic => // flowlint-next-line sketchy-null-string:off + diagnostic.trace || diagnostic.text && diagnostic.text.includes('\n'));return _react.createElement('div', { onFocus: this._handleFocus, tabIndex: -1, style: { display: 'flex', flex: 1, flexDirection: 'column', width: '100%' } }, _react.createElement((_Toolbar || _load_Toolbar()).Toolbar, { location: 'top' }, _react.createElement((_ToolbarLeft || _load_ToolbarLeft()).ToolbarLeft, null, _react.createElement((_ButtonGroup || _load_ButtonGroup()).ButtonGroup, { className: 'inline-block' }, groups.map(group => _react.createElement((_FilterButton || _load_FilterButton()).default, { key: group, group: group, selected: !this.props.hiddenGroups.has(group), onClick: () => {this.props.onTypeFilterChange(group);} }))), _react.createElement((_RegExpFilter || _load_RegExpFilter()).default, { value: this.props.textFilter, onChange: this.props.onTextFilterChange }), _react.createElement((_Toggle || _load_Toggle()).Toggle, { className: 'inline-block', onChange: this._handleFilterByActiveTextEditorChange, toggled: this.props.filterByActiveTextEditor, label: 'Current File Only' })), _react.createElement((_ToolbarRight || _load_ToolbarRight()).ToolbarRight, null, showFullDescriptionToggle ? _react.createElement((_Toggle || _load_Toggle()).Toggle, { className: 'inline-block', onChange: this._handleShowTracesChange, toggled: this.props.showTraces, label: 'Full Description' }) : null, _react.createElement((_Button || _load_Button()).Button, { onClick: this._openAllFilesWithErrors, size: (_Button || _load_Button()).ButtonSizes.SMALL, disabled: diagnostics.length === 0, className: 'inline-block', title: 'Open All' }, 'Open All'), _react.createElement((_Button || _load_Button()).Button, { icon: 'gear', size: (_Button || _load_Button()).ButtonSizes.SMALL, onClick: this._showSettings }))), _react.createElement((_DiagnosticsTable || _load_DiagnosticsTable()).default, { ref: table => {this._table = table;}, showFileName: !this.props.filterByActiveTextEditor, diagnostics: diagnostics, showDirectoryColumn: showDirectoryColumn, showTraces: showTraces, selectedMessage: this.props.selectedMessage, selectMessage: this.props.selectMessage, gotoMessageLocation: this.props.gotoMessageLocation }));}}exports.default = DiagnosticsView; \ No newline at end of file diff --git a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/FilterButton.js b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/FilterButton.js index a7885750..3a4a55f0 100644 --- a/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/FilterButton.js +++ b/modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/ui/FilterButton.js @@ -1,38 +1,38 @@ -/** - * 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 - * @format - */ - -import type {DiagnosticGroup} from '../types'; - -import {Button, ButtonSizes} from 'nuclide-commons-ui/Button'; -import * as React from 'react'; -import * as GroupUtils from '../GroupUtils'; - -type Props = {| - group: DiagnosticGroup, - selected: boolean, - onClick: () => mixed, -|}; - -export default function FilterButton(props: Props): React.Node { - const {selected, group} = props; - const displayName = GroupUtils.getDisplayName(group); - const title = props.selected ? `Hide ${displayName}` : `Show ${displayName}`; - return ( -
- - ); -}; + first: 3, + second: 4, + third: 100 } }]; + + -class SortableTableExample extends React.Component< - mixed, - { - rows: Array, - sortDescending: boolean, - sortedColumn: ?string, - }, -> { - constructor(props: mixed) { - super(props); - const rows = [ - { - data: { - first: 1, - second: 3, - third: 300, - }, - }, - { - data: { - first: 2, - second: 5, - third: 200, - }, - }, - { - className: 'nuclide-ui-custom-classname-example', - data: { - first: 3, - second: 4, - third: 100, - }, - }, - ]; this.state = { sortDescending: false, sortedColumn: null, - rows, - }; - (this: any)._handleSort = this._handleSort.bind(this); + rows }; + + this._handleSort = this._handleSort.bind(this); } - _handleSort(sortedColumn: ?string, sortDescending: boolean): void { + _handleSort(sortedColumn, sortDescending) { const sortedRows = this.state.rows.sort((obj1, obj2) => { const order = sortDescending ? -1 : 1; return order * (obj1.data[sortedColumn] - obj2.data[sortedColumn]); @@ -129,81 +129,78 @@ class SortableTableExample extends React.Component< this.setState({ rows: sortedRows, sortedColumn, - sortDescending, - }); - } + sortDescending }); - render(): React.Node { - const columns = [ - { - title: 'first', - key: 'first', - }, - { - title: 'second', - key: 'second', - }, - { - title: 'third', - key: 'third', - }, - ]; - return ( - -
( -
An optional, custom "empty message" component.
- )} - columns={columns} - rows={this.state.rows} - sortable={true} - onSort={this._handleSort} - sortedColumn={this.state.sortedColumn} - sortDescending={this.state.sortDescending} - /> - - ); } -} -const EmptyTableExample = (): React.Element => { - const columns = [ + render() { + const columns = [ { - title: 'first column', - key: 'first', - }, + title: 'first', + key: 'first' }, + { - title: 'second column', - key: 'second', - }, + title: 'second', + key: 'second' }, + { - title: 'third column', - key: 'third', - }, - ]; + title: 'third', + key: 'third' }]; + + + return ( + _react.createElement((_Block || _load_Block()).Block, null, + _react.createElement((_Table || _load_Table()).Table, { + emptyComponent: () => + _react.createElement('div', null, 'An optional, custom "empty message" component.'), + + columns: columns, + rows: this.state.rows, + sortable: true, + onSort: this._handleSort, + sortedColumn: this.state.sortedColumn, + sortDescending: this.state.sortDescending }))); + + + + }} + + +const EmptyTableExample = () => { + const columns = [ + { + title: 'first column', + key: 'first' }, + + { + title: 'second column', + key: 'second' }, + + { + title: 'third column', + key: 'third' }]; + + const rows = []; return ( - -
- - ); + _react.createElement((_Block || _load_Block()).Block, null, + _react.createElement((_Table || _load_Table()).Table, { columns: columns, rows: rows }))); + + }; -export const TableExamples = { +const TableExamples = exports.TableExamples = { sectionName: 'Table', description: '', examples: [ - { - title: 'Simple Table', - component: TableExample, - }, - { - title: 'Sortable Table', - component: SortableTableExample, - }, - { - title: 'Empty Table', - component: EmptyTableExample, - }, - ], -}; + { + title: 'Simple Table', + component: TableExample }, + + { + title: 'Sortable Table', + component: SortableTableExample }, + + { + title: 'Empty Table', + component: EmptyTableExample }] }; \ No newline at end of file diff --git a/modules/nuclide-commons-ui/Table.js b/modules/nuclide-commons-ui/Table.js index 79c5ecfd..e83f0df3 100644 --- a/modules/nuclide-commons-ui/Table.js +++ b/modules/nuclide-commons-ui/Table.js @@ -1,189 +1,849 @@ -/** - * 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 - * @format - */ - -import invariant from 'assert'; -import nullthrows from 'nullthrows'; -import classnames from 'classnames'; -import * as React from 'react'; -import {Observable, Subject} from 'rxjs'; -import shallowEqual from 'shallowequal'; -import {Icon} from './Icon'; -import { - areSetsEqual, - objectMapValues, - objectFromPairs, - arrayEqual, -} from 'nuclide-commons/collection'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {ResizeObservable} from './observable-dom'; -import {scrollIntoViewIfNeeded} from './scrollIntoView'; - -type SelectionEvent = SyntheticEvent<*> | Event; - -const DEFAULT_MIN_COLUMN_WIDTH = 40; - -const DefaultEmptyComponent = () => ( -
Empty table
-); - -export type Column = { - title: string, - key: $Keys, - // Percentage. The `width`s of all columns must add up to 1. - width?: number, - // Optional React component for rendering cell contents. - // The component receives the cell value via `props.data`. - component?: React.ComponentType, - shouldRightAlign?: boolean, - // A class to add to the cell. This will be added to both the header and body; you can - // differentiate between them with `.nuclide-ui-table-header-cell` and - // `.nuclide-ui-table-body-cell`. - cellClassName?: string, - // A minimum width (in pixels) for the column. - minWidth?: number, -}; - -export type Row = { - className?: string, - data: T, - rowAttributes?: Object, -}; - -type PercentageWidthMap = {[key: $Keys]: number}; -// Same shape; the separate type is just used for documentation--Flow doesn't recognize a -// difference. -type PixelWidthMap = {[key: $Keys]: number}; - -type Props = { - /** - * Optional classname for the entire table. - */ - className?: string, - /** - * Optional max-height for the body container. - * Useful for making the table scrollable while keeping the header fixed. - */ - maxBodyHeight?: string, - columns: Array>, - rows: Array>, - /** - * Whether to shade even and odd items differently. Default behavior is `true`. - */ - alternateBackground?: number, - /** - * Whether column widths can be resized interactively via drag&drop. Default behavior is `true`. - */ - resizable?: boolean, - children?: React.Element, - /** - * Whether columns can be sorted. - * If specified, `onSort`, `sortedColumn`, and `sortDescending` must also be specified. - */ - sortable?: boolean, - onSort?: (sortedBy: $Keys, sortDescending: boolean) => void, - sortedColumn?: ?$Keys, - sortDescending?: boolean, - /** - * Whether items can be selected. - * If specified, `onSelect` must also be specified. - */ - selectable?: boolean | ((row: T) => boolean), - selectedIndex?: ?number, - /** - * Handler to be called upon selection. Called iff `selectable` is `true`. We pass along the event - * because some consumers may want to take different action depending on it. For example, if you - * click on a row in the diagnostics table, we know you want to go to that diagnostic; if you - * select it with the keyboard, you may just be doing so incidentally while moving the selection - * to another row. - */ - onSelect?: ( - selectedItem: any, - selectedIndex: number, - event: SelectionEvent, - ) => mixed, - /** - * Callback to be invoked before calling onSelect. Called iff `selectable` is `true`. - * If this callback returns false, row selection is canceled. - */ - onWillSelect?: ( - selectedItem: any, - selectedIndex: number, - event: SelectionEvent, - ) => boolean, - - /** - * Called when a row selection is confirmed. Currently, this is done either by triggering - * "core:confirm" while an item is selected or by single clicking (which selects and confirms). - * In the future, we may consider moving single click to select-only and requiring double click - * for confirmation. - */ - onConfirm?: (selectedItem: any, selectedIndex: number) => mixed, - - onBodyBlur?: (event: SyntheticEvent<*>) => mixed, - onBodyFocus?: (event: SyntheticEvent<*>) => mixed, - - /** - * Optional React Component to override the default message when zero rows are provided. - * Useful for showing loading spinners and custom messages. - */ - emptyComponent?: React.ComponentType, - /** - * Whether a table row will be collapsed if its content is too large - */ - collapsable?: boolean, - /** - * Whether there's a header title spanning all cells instead of the column titles. - * It disables the 'sortable' prop. - */ - headerTitle?: string, - /** - * Optional HTMLElement to render a custom table header. Takes precedence over - * headerTitle. - */ - headerElement?: React.Node, - - /** - * Should keyboard navigation be enabled? This option exists for historical purposes. Ideally it - * would always be enabled, however, some locations require the "native-key-bindings" class-- - * usually to enable copying to the clipboard--which prevents Atom commands from firing. - * TODO: Find an alternative means of enabling copying in those locations, always enable keyboard - * navigation, and remove this prop. - */ - enableKeyboardNavigation?: ?boolean, -}; - -type ResizeOffset = {| - deltaPx: number, // In pixels - resizerLocation: number, // The column after which the resizer is located. -|}; - -type State = {| - tableWidth: number, - - // The user's preferred column distributions. These do not take into account the minimum widths. - preferredColumnWidths: PercentageWidthMap, - - // During a drag operation, specifies the change the user desires in the column size (and to which - // column). This is kept as a separate piece of state from the calculated widths and only combined - // with them in `render()` so that we can recalculate widths if the table changes size. We could - // also support cancelation of the resize (though we don't yet). - resizeOffset: ?ResizeOffset, - - // It's awkward to have hover styling when you're using keyboard navigation and the mouse just - // happens to be over a row. Therefore, we'll keep track of when you use keyboard navigation and - // will disable the hover state until you move the mouse again. - usingKeyboard: boolean, -|}; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.Table = undefined;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +_calculateColumnWidths = _calculateColumnWidths;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +_calculatePreferredColumnWidths = _calculatePreferredColumnWidths;var _nullthrows;function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));}var _classnames;function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));}var _react = _interopRequireWildcard(require('react'));var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _shallowequal;function _load_shallowequal() {return _shallowequal = _interopRequireDefault(require('shallowequal'));}var _Icon;function _load_Icon() {return _Icon = require('./Icon');}var _collection;function _load_collection() {return _collection = require('nuclide-commons/collection');}var _UniversalDisposable;function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _observableDom;function _load_observableDom() {return _observableDom = require('./observable-dom');}var _scrollIntoView;function _load_scrollIntoView() {return _scrollIntoView = require('./scrollIntoView');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}const DEFAULT_MIN_COLUMN_WIDTH = 40; /** + * 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. + * + * + * @format + */const DefaultEmptyComponent = () => _react.createElement('div', { className: 'nuclide-ui-table-empty-message' }, 'Empty table'); // Same shape; the separate type is just used for documentation--Flow doesn't recognize a +// difference. /** * Design concerns: * @@ -210,689 +870,61 @@ type State = {| * To address these, we define our columns using percentage widths. Unfortunately, this means that * our table may behave a little strangely when the available area is less than the sum of the * minimum widths of the columns. (Ideally, the table would scroll horizontally in this case.) - */ -export class Table extends React.Component, State> { - _mouseMoveDisposable: ?IDisposable; - _rootNode: ?HTMLDivElement; - _disposables: UniversalDisposable; - _tableBody: ?HTMLElement; - - _resizeStarts: Subject<{ - event: SyntheticMouseEvent<*>, - resizerLocation: number, - }>; - - constructor(props: Props) { - super(props); - this._resizeStarts = new Subject(); - this.state = { - preferredColumnWidths: getInitialPreferredColumnWidths(props.columns), - resizeOffset: null, - tableWidth: 0, - usingKeyboard: false, - }; - } - - shouldComponentUpdate(nextProps: Props, nextState: State): boolean { - // If the state changed, we need to re-render. - if (!shallowEqual(nextState, this.state)) { - return true; - } - - if (!shallowEqual(nextProps, this.props, compareCheapProps)) { - return true; - } - - if (!arrayEqual(nextProps.columns, this.props.columns, shallowEqual)) { - return true; - } - - if (!arrayEqual(nextProps.rows, this.props.rows)) { - return true; - } - - return false; - } - - componentDidMount(): void { - const el = nullthrows(this._rootNode); - - this._disposables = new UniversalDisposable( - // Update the column widths when the table is resized. - new ResizeObservable(el) - .startWith((null: any)) - .map(() => el.offsetWidth) - .filter(tableWidth => tableWidth > 0) - .subscribe(tableWidth => { - this.setState({tableWidth}); - }), - this._resizeStarts - .switchMap(({event: startEvent, resizerLocation}) => { - const startX = startEvent.pageX; - return Observable.fromEvent(document, 'mousemove') - .takeUntil(Observable.fromEvent(document, 'mouseup')) - .map(event => ({ - deltaPx: event.pageX - startX, - resizerLocation, - })) - .concat(Observable.of(null)); - }) - .subscribe(resizeOffset => { - if (resizeOffset == null) { - // Finalize the resize by updating the user's preferred column widths to account for - // their action. Note that these preferences are only updated when columns are resized - // (NOT when the table is). This is important so that, if the user resizes the table - // such that a column is at its minimum width and then resizes the table back to its - // orignal size, their original column widths are restored. - const preferredColumnWidths = _calculatePreferredColumnWidths({ - currentWidths: this._calculateColumnWidths(), - tableWidth: this.state.tableWidth, - minWidths: getMinWidths(this.props.columns), - }); - - // Update the preferred distributions and end the resize. - this.setState({preferredColumnWidths, resizeOffset: null}); - } else { - this.setState({resizeOffset}); - } - }), - atom.commands.add(el, { - 'core:move-up': event => { - this.setState({usingKeyboard: true}); - this._moveSelection(-1, event); - }, - 'core:move-down': event => { - this.setState({usingKeyboard: true}); - this._moveSelection(1, event); - }, - 'core:confirm': event => { - this.setState({usingKeyboard: true}); - const {rows, selectedIndex, onConfirm} = this.props; - if (onConfirm == null || selectedIndex == null) { - return; - } - const selectedRow = rows[selectedIndex]; - const selectedItem = selectedRow && selectedRow.data; - if (selectedItem != null) { - onConfirm(selectedItem, selectedIndex); - } - }, - }), - () => { - if (this._mouseMoveDisposable != null) { - this._mouseMoveDisposable.dispose(); - } - }, - ); - } - - componentWillUnmount(): void { - this._disposables.dispose(); - } - - componentDidUpdate(prevProps: Props, prevState: State): void { - if ( - this._tableBody != null && - this.props.selectedIndex != null && - this.props.selectedIndex !== prevProps.selectedIndex - ) { - const selectedRow = this._tableBody.children[this.props.selectedIndex]; - if (selectedRow != null) { - scrollIntoViewIfNeeded(selectedRow); - } - } - if (this.state.usingKeyboard !== prevState.usingKeyboard) { - if (this._mouseMoveDisposable != null) { - this._mouseMoveDisposable.dispose(); - } - if (this.state.usingKeyboard) { - this._mouseMoveDisposable = new UniversalDisposable( - Observable.fromEvent(document, 'mousemove') - .take(1) - .subscribe(() => { - this.setState({usingKeyboard: false}); - }), - ); - } - } - } - - focus(): void { - if (this._tableBody == null) { - return; - } - let el = document.activeElement; - while (el != null) { - if (el === this._tableBody) { - // Already focused! - return; - } - el = el.parentNode; - } - this._tableBody.focus(); - } - - componentWillReceiveProps(nextProps: Props): void { - // Did the columns change? If so, we need to recalculate the widths. - const currentColumns = this.props.columns; - const nextColumns = nextProps.columns; - if ( - nextColumns.length !== currentColumns.length || - // If the columns just changed order, we want to keep their widths. - !areSetsEqual( - new Set(currentColumns.map(column => column.key)), - new Set(nextColumns.map(column => column.key)), - ) - ) { - this.setState({ - preferredColumnWidths: getInitialPreferredColumnWidths(nextColumns), - }); - } - } - - _moveSelection(offset: -1 | 1, event: SelectionEvent): void { - const {selectedIndex} = this.props; - if (selectedIndex == null) { - return; - } - const nextSelectedIndex = Math.max( - 0, - Math.min(this.props.rows.length - 1, selectedIndex + offset), - ); - if (nextSelectedIndex === selectedIndex) { - return; - } - this._selectRow({index: nextSelectedIndex, event}); - } - - _selectRow(options: {| - index: number, - event: SelectionEvent, - confirm?: boolean, - |}): void { - const {index: selectedIndex, event, confirm} = options; - const {onSelect, onWillSelect, rows} = this.props; - if (onSelect == null) { - return; - } - const selectedRow = rows[selectedIndex]; - const selectedItem = selectedRow.data; - if (onWillSelect != null) { - if (onWillSelect(selectedItem, selectedIndex, event) === false) { - return; - } - } - onSelect(selectedItem, selectedIndex, event); - if (confirm && this.props.onConfirm != null) { - this.props.onConfirm(selectedItem, selectedIndex); - } - } - - _handleSortByColumn(sortedBy: $Keys): void { - const {onSort, sortDescending, sortedColumn} = this.props; - if (onSort == null) { - return; - } - onSort( - sortedBy, - sortDescending == null || sortedBy !== sortedColumn - ? false - : !sortDescending, - ); - } - - // Just a bound version of the `_calculateColumnWidths` function for convenience. - _calculateColumnWidths(): PercentageWidthMap { - return _calculateColumnWidths({ - preferredWidths: this.state.preferredColumnWidths, - minWidths: getMinWidths(this.props.columns), - tableWidth: this.state.tableWidth, - columnOrder: this.props.columns.map(column => column.key), - resizeOffset: this.state.resizeOffset, - }); - } - - _renderEmptyCellContent(): React.Element { - return
; - } - - render(): React.Node { - return ( -
(this._rootNode = rootNode)}> - {this._renderContents()} -
- ); - } - - _renderContents(): React.Node { - if (this.state.tableWidth === 0) { - // We don't have the table width yet so we can't render the columns. - return null; - } - - const { - alternateBackground, - columns, - headerElement, - headerTitle, - maxBodyHeight, - rows, - selectable, - selectedIndex, - sortable, - sortedColumn, - sortDescending, - } = this.props; - - const columnWidths = this._calculateColumnWidths(); - - const header = - headerElement != null || headerTitle != null ? ( -
- {headerElement != null ? headerElement : headerTitle} -
- ) : ( - columns.map((column, i) => { - const {title, key, shouldRightAlign, cellClassName} = column; - let resizer; - if (i < columns.length - 1) { - resizer = ( -
{ - this._resizeStarts.next({event, resizerLocation: i}); - }} - onClick={(e: SyntheticMouseEvent<>) => { - // Prevent sortable column header click event from firing. - e.stopPropagation(); - }} - /> - ); - } - const width = columnWidths[key]; - const optionalHeaderCellProps = {}; - if (width != null) { - optionalHeaderCellProps.style = {width: `${width * 100}%`}; - } - let sortIndicator; - let titleOverlay = title; - if (sortable) { - optionalHeaderCellProps.onClick = () => { - this._handleSortByColumn(key); - }; - titleOverlay += ' – click to sort'; - if (sortedColumn === key) { - sortIndicator = ( - - - - ); - } - } - return ( -
- {title} - {sortIndicator} - {resizer} -
- ); - }) - ); - let body = rows.map((row, i) => { - const {className: rowClassName, data, rowAttributes} = row; - const renderedRow = columns.map((column, j) => { - const { - key, - cellClassName, - component: Component, - shouldRightAlign, - } = column; - let datum = data[key]; - if (Component != null) { - datum = ; - } else if (datum == null) { - datum = this._renderEmptyCellContent(); - } - const cellStyle = {}; - const width = columnWidths[key]; - if (width != null) { - cellStyle.width = `${width * 100}%`; - } - return ( -
- {datum} -
- ); - }); - const selectableRow = - typeof selectable === 'function' ? selectable(row.data) : selectable; - const rowProps = selectableRow - ? { - onClick: event => { - switch (event.detail) { - // This (`event.detail === 0`) shouldn't happen normally but does when the click is - // triggered by the integration test. - case 0: - case 1: - this._selectRow({index: i, event}); - return; - case 2: - // We need to check `event.detail` (instead of using `onDoubleClick`) because - // (for some reason) `onDoubleClick` is only firing sporadically. - // TODO: Figure out why. Repros in the diagnostic table with React 16.0.0 and - // Atom 1.22.0-beta1 (Chrome 56.0.2924.87). This may be because we're swapping out - // the component on the click so a different one is receiving the second? - this._selectRow({index: i, event, confirm: true}); - return; - } - }, - } - : {}; - const isSelectedRow = selectedIndex != null && i === selectedIndex; - return ( -
- {renderedRow} -
- ); - }); - if (rows.length === 0) { - const EmptyComponent = this.props.emptyComponent || DefaultEmptyComponent; - body = ; - } - const scrollableBodyStyle = {}; - if (maxBodyHeight != null) { - scrollableBodyStyle.maxHeight = maxBodyHeight; - scrollableBodyStyle.overflowY = 'auto'; - } - const bodyClassNames = classnames( - 'nuclide-ui-table', - 'nuclide-ui-table-body', - { - // Using native-key-bindings prevents the up and down arrows from being captured. - 'native-key-bindings': !this.props.enableKeyboardNavigation, - // Only enable text selection if the rows aren't selectable as these two things conflict. - // TODO: Add the ability to copy text that doesn't involve text selection within selections. - 'nuclide-ui-table-body-selectable-text': !this.props.selectable, - }, - ); - return [ -
-
{header}
-
, -
{ - if (this.props.onBodyFocus != null) { - this.props.onBodyFocus(event); - } - }} - onBlur={event => { - if (this.props.onBodyBlur != null) { - this.props.onBodyBlur(event); - } - }}> -
{ - this._tableBody = el; - }} - className={bodyClassNames} - tabIndex="-1"> - {body} -
-
, - ]; - } -} - -/** - * Get the initial size of each column as a percentage of the total. - */ -function getInitialPreferredColumnWidths( - columns: Array>, -): PercentageWidthMap { - const columnWidthRatios = {}; - let assignedWidth = 0; - const unresolvedColumns = []; - columns.forEach(column => { - const {key, width} = column; - if (width != null) { - columnWidthRatios[key] = width; - assignedWidth += width; - } else { - unresolvedColumns.push(column); - } - }); - const residualColumnWidth = (1 - assignedWidth) / unresolvedColumns.length; - unresolvedColumns.forEach(column => { - columnWidthRatios[column.key] = residualColumnWidth; - }); - return columnWidthRatios; -} - -function getMinWidths(columns: Array>): PixelWidthMap { - const minWidths = {}; - columns.forEach(column => { - minWidths[column.key] = - column.minWidth == null ? DEFAULT_MIN_COLUMN_WIDTH : column.minWidth; - }); - return minWidths; -} - -/** - * Calculate widths, taking into account the preferred and minimum widths. Exported for testing - * only. - */ -export function _calculateColumnWidths(options: { - preferredWidths: PercentageWidthMap, - minWidths: PixelWidthMap, - tableWidth: number, - columnOrder: Array<$Keys>, - resizeOffset: ?ResizeOffset, -}): PercentageWidthMap { - const { - preferredWidths, - minWidths: minWidthsPx, - tableWidth, - columnOrder, - resizeOffset: resizeOffset_, - } = options; - const resizeOffset = resizeOffset_ || {deltaPx: 0, resizerLocation: 0}; - const widthsPx = {}; - - // Calculate the pixel widths of each column given its desired percentage width and minimum pixel + */class Table extends _react.Component {constructor(props) {super(props);this._resizeStarts = new _rxjsBundlesRxMinJs.Subject();this.state = { preferredColumnWidths: getInitialPreferredColumnWidths(props.columns), resizeOffset: null, tableWidth: 0, usingKeyboard: false };}shouldComponentUpdate(nextProps, nextState) {// If the state changed, we need to re-render. + if (!(0, (_shallowequal || _load_shallowequal()).default)(nextState, this.state)) {return true;}if (!(0, (_shallowequal || _load_shallowequal()).default)(nextProps, this.props, compareCheapProps)) {return true;}if (!(0, (_collection || _load_collection()).arrayEqual)(nextProps.columns, this.props.columns, (_shallowequal || _load_shallowequal()).default)) {return true;}if (!(0, (_collection || _load_collection()).arrayEqual)(nextProps.rows, this.props.rows)) {return true;}return false;}componentDidMount() {const el = (0, (_nullthrows || _load_nullthrows()).default)(this._rootNode);this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default( // Update the column widths when the table is resized. + new (_observableDom || _load_observableDom()).ResizeObservable(el).startWith(null).map(() => el.offsetWidth).filter(tableWidth => tableWidth > 0).subscribe(tableWidth => {this.setState({ tableWidth });}), this._resizeStarts.switchMap(({ event: startEvent, resizerLocation }) => {const startX = startEvent.pageX;return _rxjsBundlesRxMinJs.Observable.fromEvent(document, 'mousemove').takeUntil(_rxjsBundlesRxMinJs.Observable.fromEvent(document, 'mouseup')).map(event => ({ deltaPx: event.pageX - startX, resizerLocation })).concat(_rxjsBundlesRxMinJs.Observable.of(null));}).subscribe(resizeOffset => {if (resizeOffset == null) {// Finalize the resize by updating the user's preferred column widths to account for + // their action. Note that these preferences are only updated when columns are resized + // (NOT when the table is). This is important so that, if the user resizes the table + // such that a column is at its minimum width and then resizes the table back to its + // orignal size, their original column widths are restored. + const preferredColumnWidths = _calculatePreferredColumnWidths({ currentWidths: this._calculateColumnWidths(), tableWidth: this.state.tableWidth, minWidths: getMinWidths(this.props.columns) }); // Update the preferred distributions and end the resize. + this.setState({ preferredColumnWidths, resizeOffset: null });} else {this.setState({ resizeOffset });}}), atom.commands.add(el, { 'core:move-up': event => {this.setState({ usingKeyboard: true });this._moveSelection(-1, event);}, 'core:move-down': event => {this.setState({ usingKeyboard: true });this._moveSelection(1, event);}, 'core:confirm': event => {this.setState({ usingKeyboard: true });const { rows, selectedIndex, onConfirm } = this.props;if (onConfirm == null || selectedIndex == null) {return;}const selectedRow = rows[selectedIndex];const selectedItem = selectedRow && selectedRow.data;if (selectedItem != null) {onConfirm(selectedItem, selectedIndex);}} }), () => {if (this._mouseMoveDisposable != null) {this._mouseMoveDisposable.dispose();}});}componentWillUnmount() {this._disposables.dispose();}componentDidUpdate(prevProps, prevState) {if (this._tableBody != null && this.props.selectedIndex != null && this.props.selectedIndex !== prevProps.selectedIndex) {const selectedRow = this._tableBody.children[this.props.selectedIndex];if (selectedRow != null) {(0, (_scrollIntoView || _load_scrollIntoView()).scrollIntoViewIfNeeded)(selectedRow);}}if (this.state.usingKeyboard !== prevState.usingKeyboard) {if (this._mouseMoveDisposable != null) {this._mouseMoveDisposable.dispose();}if (this.state.usingKeyboard) {this._mouseMoveDisposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(_rxjsBundlesRxMinJs.Observable.fromEvent(document, 'mousemove').take(1).subscribe(() => {this.setState({ usingKeyboard: false });}));}}}focus() {if (this._tableBody == null) {return;}let el = document.activeElement;while (el != null) {if (el === this._tableBody) {// Already focused! + return;}el = el.parentNode;}this._tableBody.focus();}componentWillReceiveProps(nextProps) {// Did the columns change? If so, we need to recalculate the widths. + const currentColumns = this.props.columns;const nextColumns = nextProps.columns;if (nextColumns.length !== currentColumns.length || // If the columns just changed order, we want to keep their widths. + !(0, (_collection || _load_collection()).areSetsEqual)(new Set(currentColumns.map(column => column.key)), new Set(nextColumns.map(column => column.key)))) {this.setState({ preferredColumnWidths: getInitialPreferredColumnWidths(nextColumns) });}}_moveSelection(offset, event) {const { selectedIndex } = this.props;if (selectedIndex == null) {return;}const nextSelectedIndex = Math.max(0, Math.min(this.props.rows.length - 1, selectedIndex + offset));if (nextSelectedIndex === selectedIndex) {return;}this._selectRow({ index: nextSelectedIndex, event });}_selectRow(options) {const { index: selectedIndex, event, confirm } = options;const { onSelect, onWillSelect, rows } = this.props;if (onSelect == null) {return;}const selectedRow = rows[selectedIndex];const selectedItem = selectedRow.data;if (onWillSelect != null) {if (onWillSelect(selectedItem, selectedIndex, event) === false) {return;}}onSelect(selectedItem, selectedIndex, event);if (confirm && this.props.onConfirm != null) {this.props.onConfirm(selectedItem, selectedIndex);}}_handleSortByColumn(sortedBy) {const { onSort, sortDescending, sortedColumn } = this.props;if (onSort == null) {return;}onSort(sortedBy, sortDescending == null || sortedBy !== sortedColumn ? false : !sortDescending);} // Just a bound version of the `_calculateColumnWidths` function for convenience. + _calculateColumnWidths() {return _calculateColumnWidths({ preferredWidths: this.state.preferredColumnWidths, minWidths: getMinWidths(this.props.columns), tableWidth: this.state.tableWidth, columnOrder: this.props.columns.map(column => column.key), resizeOffset: this.state.resizeOffset });}_renderEmptyCellContent() {return _react.createElement('div', null);}render() {return _react.createElement('div', { className: this.props.className, ref: rootNode => this._rootNode = rootNode }, this._renderContents());}_renderContents() {if (this.state.tableWidth === 0) {// We don't have the table width yet so we can't render the columns. + return null;}const { alternateBackground, columns, headerElement, headerTitle, maxBodyHeight, rows, selectable, selectedIndex, sortable, sortedColumn, sortDescending } = this.props;const columnWidths = this._calculateColumnWidths();const header = headerElement != null || headerTitle != null ? _react.createElement('div', { className: 'nuclide-ui-table-header-cell nuclide-ui-table-full-header' }, headerElement != null ? headerElement : headerTitle) : columns.map((column, i) => {const { title, key, shouldRightAlign, cellClassName } = column;let resizer;if (i < columns.length - 1) {resizer = _react.createElement('div', { className: 'nuclide-ui-table-header-resize-handle', onMouseDown: event => {this._resizeStarts.next({ event, resizerLocation: i });}, onClick: e => {// Prevent sortable column header click event from firing. + e.stopPropagation();} });}const width = columnWidths[key];const optionalHeaderCellProps = {};if (width != null) {optionalHeaderCellProps.style = { width: `${width * 100}%` };}let sortIndicator;let titleOverlay = title;if (sortable) {optionalHeaderCellProps.onClick = () => {this._handleSortByColumn(key);};titleOverlay += ' – click to sort';if (sortedColumn === key) {sortIndicator = _react.createElement('span', { className: 'nuclide-ui-table-sort-indicator' }, _react.createElement((_Icon || _load_Icon()).Icon, { icon: sortDescending ? 'triangle-down' : 'triangle-up' }));}}return _react.createElement('div', Object.assign({ className: (0, (_classnames || _load_classnames()).default)(cellClassName, { 'nuclide-ui-table-cell-text-align-right': shouldRightAlign, 'nuclide-ui-table-header-cell': true, 'nuclide-ui-table-header-cell-sortable': sortable }), title: titleOverlay, key: key }, optionalHeaderCellProps), title, sortIndicator, resizer);});let body = rows.map((row, i) => {const { className: rowClassName, data, rowAttributes } = row;const renderedRow = columns.map((column, j) => {const { key, cellClassName, component: Component, shouldRightAlign } = column;let datum = data[key];if (Component != null) {datum = _react.createElement(Component, { data: datum });} else if (datum == null) {datum = this._renderEmptyCellContent();}const cellStyle = {};const width = columnWidths[key];if (width != null) {cellStyle.width = `${width * 100}%`;}return _react.createElement('div', Object.assign({ className: (0, (_classnames || _load_classnames()).default)(cellClassName, { 'nuclide-ui-table-body-cell': true, 'nuclide-ui-table-cell-text-align-right': shouldRightAlign }), key: j, style: cellStyle, title: typeof datum !== 'object' ? String(datum) : null }, rowAttributes), datum);});const selectableRow = typeof selectable === 'function' ? selectable(row.data) : selectable;const rowProps = selectableRow ? { onClick: event => {switch (event.detail) {// This (`event.detail === 0`) shouldn't happen normally but does when the click is + // triggered by the integration test. + case 0:case 1:this._selectRow({ index: i, event });return;case 2: // We need to check `event.detail` (instead of using `onDoubleClick`) because + // (for some reason) `onDoubleClick` is only firing sporadically. + // TODO: Figure out why. Repros in the diagnostic table with React 16.0.0 and + // Atom 1.22.0-beta1 (Chrome 56.0.2924.87). This may be because we're swapping out + // the component on the click so a different one is receiving the second? + this._selectRow({ index: i, event, confirm: true });return;}} } : {};const isSelectedRow = selectedIndex != null && i === selectedIndex;return _react.createElement('div', Object.assign({ className: (0, (_classnames || _load_classnames()).default)(rowClassName, { 'nuclide-ui-table-row': true, 'nuclide-ui-table-row-selectable': selectableRow, 'nuclide-ui-table-row-disabled': typeof selectable === 'function' && !selectableRow, 'nuclide-ui-table-row-using-keyboard-nav': this.state.usingKeyboard, 'nuclide-ui-table-row-selected': isSelectedRow, 'nuclide-ui-table-row-alternate': alternateBackground !== false && i % 2 === 1, 'nuclide-ui-table-collapsed-row': this.props.collapsable && !isSelectedRow }), 'data-row-index': i, key: i }, rowProps), renderedRow);});if (rows.length === 0) {const EmptyComponent = this.props.emptyComponent || DefaultEmptyComponent;body = _react.createElement(EmptyComponent, null);}const scrollableBodyStyle = {};if (maxBodyHeight != null) {scrollableBodyStyle.maxHeight = maxBodyHeight;scrollableBodyStyle.overflowY = 'auto';}const bodyClassNames = (0, (_classnames || _load_classnames()).default)('nuclide-ui-table', 'nuclide-ui-table-body', { // Using native-key-bindings prevents the up and down arrows from being captured. + 'native-key-bindings': !this.props.enableKeyboardNavigation, // Only enable text selection if the rows aren't selectable as these two things conflict. + // TODO: Add the ability to copy text that doesn't involve text selection within selections. + 'nuclide-ui-table-body-selectable-text': !this.props.selectable });return [_react.createElement('div', { key: 'header', className: 'nuclide-ui-table' }, _react.createElement('div', { className: 'nuclide-ui-table-header' }, header)), _react.createElement('div', { key: 'body', style: scrollableBodyStyle, onFocus: event => {if (this.props.onBodyFocus != null) {this.props.onBodyFocus(event);}}, onBlur: event => {if (this.props.onBodyBlur != null) {this.props.onBodyBlur(event);}} }, _react.createElement('div', { ref: el => {this._tableBody = el;}, className: bodyClassNames, tabIndex: '-1' }, body))];}}exports.Table = Table; /** + * Get the initial size of each column as a percentage of the total. + */function getInitialPreferredColumnWidths(columns) {const columnWidthRatios = {};let assignedWidth = 0;const unresolvedColumns = [];columns.forEach(column => {const { key, width } = column;if (width != null) {columnWidthRatios[key] = width;assignedWidth += width;} else {unresolvedColumns.push(column);}});const residualColumnWidth = (1 - assignedWidth) / unresolvedColumns.length;unresolvedColumns.forEach(column => {columnWidthRatios[column.key] = residualColumnWidth;});return columnWidthRatios;}function getMinWidths(columns) {const minWidths = {};columns.forEach(column => {minWidths[column.key] = column.minWidth == null ? DEFAULT_MIN_COLUMN_WIDTH : column.minWidth;});return minWidths;} /** + * Calculate widths, taking into account the preferred and minimum widths. Exported for testing + * only. + */function _calculateColumnWidths(options) {const { preferredWidths, minWidths: minWidthsPx, tableWidth, columnOrder, resizeOffset: resizeOffset_ } = options;const resizeOffset = resizeOffset_ || { deltaPx: 0, resizerLocation: 0 };const widthsPx = {}; // Calculate the pixel widths of each column given its desired percentage width and minimum pixel // width. - { - // Figure out how many pixels each column wants, given the current available width. - let widthToAllocate = tableWidth; - let columnsToAllocate = columnOrder; - while (columnsToAllocate.length > 0 && widthToAllocate > 0) { - const remainingPct = columnsToAllocate - .map(columnName => preferredWidths[columnName]) - .reduce((a, b) => a + b, 0); - const desiredWidthsPx = objectFromPairs( - columnsToAllocate.map(columnName => { - const desiredPct = preferredWidths[columnName] / remainingPct; - const desiredPx = Math.round(desiredPct * widthToAllocate); - return [columnName, desiredPx]; - }), - ); - - // Allocate widths for the columns who want less than their minimum width. - let remainingPx = widthToAllocate; - let remainingColumns = []; - columnsToAllocate.forEach(columnName => { - const desiredPx = desiredWidthsPx[columnName]; - const minPx = minWidthsPx[columnName]; - if (minPx >= desiredPx) { - widthsPx[columnName] = Math.min(minPx, remainingPx); - remainingPx -= widthsPx[columnName]; - } else { - remainingColumns.push(columnName); - } - }); - - // If we didn't need to truncate any of the columns, give them all their desired width. - if (columnsToAllocate.length === remainingColumns.length) { - Object.assign(widthsPx, desiredWidthsPx); - remainingColumns = []; - } - - // If we had to truncate any of the columns, that changes the calculations for how big the + {// Figure out how many pixels each column wants, given the current available width. + let widthToAllocate = tableWidth;let columnsToAllocate = columnOrder;while (columnsToAllocate.length > 0 && widthToAllocate > 0) {const remainingPct = columnsToAllocate.map(columnName => preferredWidths[columnName]).reduce((a, b) => a + b, 0);const desiredWidthsPx = (0, (_collection || _load_collection()).objectFromPairs)(columnsToAllocate.map(columnName => {const desiredPct = preferredWidths[columnName] / remainingPct;const desiredPx = Math.round(desiredPct * widthToAllocate);return [columnName, desiredPx];})); // Allocate widths for the columns who want less than their minimum width. + let remainingPx = widthToAllocate;let remainingColumns = [];columnsToAllocate.forEach(columnName => {const desiredPx = desiredWidthsPx[columnName];const minPx = minWidthsPx[columnName];if (minPx >= desiredPx) {widthsPx[columnName] = Math.min(minPx, remainingPx);remainingPx -= widthsPx[columnName];} else {remainingColumns.push(columnName);}}); // If we didn't need to truncate any of the columns, give them all their desired width. + if (columnsToAllocate.length === remainingColumns.length) {Object.assign(widthsPx, desiredWidthsPx);remainingColumns = [];} // If we had to truncate any of the columns, that changes the calculations for how big the // remaining columns want to be, so make another pass. - widthToAllocate = remainingPx; - columnsToAllocate = remainingColumns; - } - } - - { - // Adjust the column widths according to the resized column. - const {deltaPx, resizerLocation} = resizeOffset; - const leftColumns = columnOrder.slice(0, resizerLocation + 1); - const rightColumns = columnOrder.slice(resizerLocation + 1); - - const [shrinkingColumns, growingColumn] = - deltaPx < 0 - ? [leftColumns.reverse(), rightColumns[0]] - : [rightColumns, leftColumns[leftColumns.length - 1]]; - const targetChange = Math.abs(deltaPx); - let cumulativeChange = 0; - - for (const columnName of shrinkingColumns) { - const startWidth = widthsPx[columnName]; - const minWidth = minWidthsPx[columnName]; - const remainingWidth = targetChange - cumulativeChange; - const newWidth = Math.max(minWidth, startWidth - remainingWidth); - const change = Math.abs(startWidth - newWidth); - cumulativeChange += change; - widthsPx[columnName] = newWidth; - if (cumulativeChange >= targetChange) { - break; - } - } - - widthsPx[growingColumn] += cumulativeChange; - } - - // Convert all the widths from pixels to percentages. - const widths = {}; - { - let remainingWidth = 1; - columnOrder.forEach((columnName, i) => { - const isLastColumn = i === columnOrder.length - 1; - if (isLastColumn) { - // Give the last column all the remaining to account for rounding issues. - widths[columnName] = remainingWidth; - } else { - widths[columnName] = widthsPx[columnName] / tableWidth; - remainingWidth -= widths[columnName]; - } - }); - } - - return widths; -} - -/** - * Given the current (percentage) widths of each column, determines what user-preferred distribution - * this represents. Exported for testing only. - */ -export function _calculatePreferredColumnWidths(options: { - currentWidths: PercentageWidthMap, - tableWidth: number, - minWidths: PixelWidthMap, -}): PercentageWidthMap { - const {currentWidths, tableWidth, minWidths: minWidthsPx} = options; - const currentWidthsPx = objectMapValues(currentWidths, w => w * tableWidth); - - // If any column is at its minimum width, we take that to mean that the user wants the column + widthToAllocate = remainingPx;columnsToAllocate = remainingColumns;}}{// Adjust the column widths according to the resized column. + const { deltaPx, resizerLocation } = resizeOffset;const leftColumns = columnOrder.slice(0, resizerLocation + 1);const rightColumns = columnOrder.slice(resizerLocation + 1);const [shrinkingColumns, growingColumn] = deltaPx < 0 ? [leftColumns.reverse(), rightColumns[0]] : [rightColumns, leftColumns[leftColumns.length - 1]];const targetChange = Math.abs(deltaPx);let cumulativeChange = 0;for (const columnName of shrinkingColumns) {const startWidth = widthsPx[columnName];const minWidth = minWidthsPx[columnName];const remainingWidth = targetChange - cumulativeChange;const newWidth = Math.max(minWidth, startWidth - remainingWidth);const change = Math.abs(startWidth - newWidth);cumulativeChange += change;widthsPx[columnName] = newWidth;if (cumulativeChange >= targetChange) {break;}}widthsPx[growingColumn] += cumulativeChange;} // Convert all the widths from pixels to percentages. + const widths = {};{let remainingWidth = 1;columnOrder.forEach((columnName, i) => {const isLastColumn = i === columnOrder.length - 1;if (isLastColumn) {// Give the last column all the remaining to account for rounding issues. + widths[columnName] = remainingWidth;} else {widths[columnName] = widthsPx[columnName] / tableWidth;remainingWidth -= widths[columnName];}});}return widths;} /** + * Given the current (percentage) widths of each column, determines what user-preferred distribution + * this represents. Exported for testing only. + */function _calculatePreferredColumnWidths(options) {const { currentWidths, tableWidth, minWidths: minWidthsPx } = options;const currentWidthsPx = (0, (_collection || _load_collection()).objectMapValues)(currentWidths, w => w * tableWidth); // If any column is at its minimum width, we take that to mean that the user wants the column // remain at its minimum if the table is resized (as opposed to maintaining the same percentage). // Accordingly, we make that column's preferred width 0. - - const preferredColumnWidths = {}; - - // Figure out which columns are at their minimum widths. + const preferredColumnWidths = {}; // Figure out which columns are at their minimum widths. let remainingPx = 0; // The width that isn't accounted for after minWidth. - const columnsNotAtMinimum = []; - for (const [columnName, widthPx] of Object.entries(currentWidthsPx)) { - invariant(typeof widthPx === 'number'); - const minWidthPx = minWidthsPx[columnName]; - if (Math.floor(widthPx) <= minWidthPx) { - // Keep it at its min-width. - preferredColumnWidths[columnName] = 0; - } else { - remainingPx += widthPx; - columnsNotAtMinimum.push([columnName, widthPx]); - } - } - - // Now distribute the widths of the other columns. - let remainingPct = 1; - columnsNotAtMinimum.forEach(([columnName, width], index) => { - const isLastColumn = index === columnsNotAtMinimum.length - 1; - if (isLastColumn) { - // We give the last column the remaining width just to be certain they all add up to 1. - preferredColumnWidths[columnName] = remainingPct; - } else { - preferredColumnWidths[columnName] = width / remainingPx; - remainingPct -= preferredColumnWidths[columnName]; - } - }); - - return preferredColumnWidths; -} - -/** - * An equality check for comparing Props using `shallowEqual()`. This only performs the cheap - * checks and assumes that the rows and columns are equal. (They can be checked separatedly iff - * necessary.) - */ -function compareCheapProps(a: mixed, b: mixed, key: ?string): ?boolean { - switch (key) { - case undefined: - // This is a magic way of telling `shallowEqual()` to use the default comparison for the + const columnsNotAtMinimum = [];for (const [columnName, widthPx] of Object.entries(currentWidthsPx)) {if (!(typeof widthPx === 'number')) {throw new Error('Invariant violation: "typeof widthPx === \'number\'"');}const minWidthPx = minWidthsPx[columnName];if (Math.floor(widthPx) <= minWidthPx) {// Keep it at its min-width. + preferredColumnWidths[columnName] = 0;} else {remainingPx += widthPx;columnsNotAtMinimum.push([columnName, widthPx]);}} // Now distribute the widths of the other columns. + let remainingPct = 1;columnsNotAtMinimum.forEach(([columnName, width], index) => {const isLastColumn = index === columnsNotAtMinimum.length - 1;if (isLastColumn) {// We give the last column the remaining width just to be certain they all add up to 1. + preferredColumnWidths[columnName] = remainingPct;} else {preferredColumnWidths[columnName] = width / remainingPx;remainingPct -= preferredColumnWidths[columnName];}});return preferredColumnWidths;} /** + * An equality check for comparing Props using `shallowEqual()`. This only performs the cheap + * checks and assumes that the rows and columns are equal. (They can be checked separatedly iff + * necessary.) + */function compareCheapProps(a, b, key) {switch (key) {case undefined: // This is a magic way of telling `shallowEqual()` to use the default comparison for the // props objects (inspect its members). - return undefined; - case 'rows': - case 'columns': - // We'll check these later iff we need to since they're more expensive. - return true; - default: - return a === b; - } -} + return undefined;case 'rows':case 'columns': // We'll check these later iff we need to since they're more expensive. + return true;default:return a === b;}} \ No newline at end of file diff --git a/modules/nuclide-commons-ui/Tabs.example.js b/modules/nuclide-commons-ui/Tabs.example.js index 8d47ef8e..9a58ec2c 100644 --- a/modules/nuclide-commons-ui/Tabs.example.js +++ b/modules/nuclide-commons-ui/Tabs.example.js @@ -1,84 +1,81 @@ -/** - * 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 - * @format - */ - -import * as React from 'react'; -import {Block} from './Block'; -import Tabs from './Tabs'; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.TabExamples = undefined; + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react'));var _Block; +function _load_Block() {return _Block = require('./Block');}var _Tabs; +function _load_Tabs() {return _Tabs = _interopRequireDefault(require('./Tabs'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} const tabs = [ - { - name: 'one', - tabContent:
One
, - }, - { - name: 'two', - tabContent:
Two
, - }, - { - name: 'three', - tabContent:
Three
, - }, - { - name: 'four', - tabContent:
Four
, - }, - { - name: 'five', - tabContent:
Five
, - }, -]; - -class TabExample extends React.Component { - constructor(props: any) { - super(props); - this.state = { - activeTabName: 'one', - }; - } - - handleTabChange = (newTabName: { - name: string, - tabContent: React.Element, - }): void => { - this.setState({ - activeTabName: newTabName.name, - }); - }; - - render(): React.Node { - const {activeTabName} = this.state; +{ + name: 'one', + tabContent: _react.createElement('div', null, 'One') }, + +{ + name: 'two', + tabContent: _react.createElement('div', null, 'Two') }, + +{ + name: 'three', + tabContent: _react.createElement('div', null, 'Three') }, + +{ + name: 'four', + tabContent: _react.createElement('div', null, 'Four') }, + +{ + name: 'five', + tabContent: _react.createElement('div', null, 'Five') }]; /** + * 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. + * + * + * @format + */class TabExample extends _react.Component {constructor(props) {super(props);this. + + handleTabChange = newTabName => + + + { + this.setState({ + activeTabName: newTabName.name }); + + };this.state = { activeTabName: 'one' };} + + render() { + const { activeTabName } = this.state; return ( - - -
- Showing content for tab "{activeTabName}". -
-
- ); - } -} - -export const TabExamples = { + _react.createElement((_Block || _load_Block()).Block, null, + _react.createElement((_Tabs || _load_Tabs()).default, { + tabs: tabs, + activeTabName: activeTabName, + triggeringEvent: 'onClick', + onActiveTabChange: this.handleTabChange }), + + _react.createElement('div', { style: { padding: '2em 0 2em 0' } }, 'Showing content for tab "', + activeTabName, '".'))); + + + + }} + + +const TabExamples = exports.TabExamples = { sectionName: 'Tabs', description: '', examples: [ - { - title: '', - component: TabExample, - }, - ], -}; + { + title: '', + component: TabExample }] }; \ No newline at end of file diff --git a/modules/nuclide-commons-ui/Tabs.js b/modules/nuclide-commons-ui/Tabs.js index 7ae9055c..c80451b1 100644 --- a/modules/nuclide-commons-ui/Tabs.js +++ b/modules/nuclide-commons-ui/Tabs.js @@ -1,82 +1,91 @@ -/** - * 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 - * @format - */ - -import type {IconName} from './Icon'; - -import {Icon} from './Icon'; -import * as React from 'react'; -import classnames from 'classnames'; -import nullthrows from 'nullthrows'; - -export type Tab = { - name: string, - icon?: IconName, - tabContent: React.Element, -}; - -type Props = { - tabs: Array, - activeTabName: ?string, - closeable: boolean, - onActiveTabChange: (tab: Tab) => void, - onClose?: () => void, - triggeringEvent: string, -}; - -export default class Tabs extends React.Component { - static defaultProps = { - closeable: false, - triggeringEvent: 'onClick', - }; - - _handleTabChange = (selectedTabName: string) => { - if (typeof this.props.onActiveTabChange === 'function') { - this.props.onActiveTabChange( - nullthrows(this.props.tabs.find(tab => tab.name === selectedTabName)), - ); - } - }; - - _renderTabMenu = (): React.Element => { - const closeButton = this.props.closeable ? ( -
- ) : null; - const tabs = this.props.tabs.map(tab => { - const icon = tab.icon == null ? null : ; - const handler = {}; - handler[this.props.triggeringEvent] = this._handleTabChange.bind( +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _Icon; + + + + + + + + + + + + + +function _load_Icon() {return _Icon = require('./Icon');} +var _react = _interopRequireWildcard(require('react'));var _classnames; +function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));}var _nullthrows; +function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} + + + + + + + + + + + + + + + + +class Tabs extends _react.Component {constructor(...args) {var _temp;return _temp = super(...args), this. + + + + + + _handleTabChange = selectedTabName => { + if (typeof this.props.onActiveTabChange === 'function') { + this.props.onActiveTabChange( + (0, (_nullthrows || _load_nullthrows()).default)(this.props.tabs.find(tab => tab.name === selectedTabName))); + + } + }, this. + + _renderTabMenu = () => { + const closeButton = this.props.closeable ? + _react.createElement('div', { className: 'close-icon', onClick: this.props.onClose }) : + null; + const tabs = this.props.tabs.map(tab => { + const icon = tab.icon == null ? null : _react.createElement((_Icon || _load_Icon()).Icon, { icon: tab.icon }); + const handler = {}; + handler[this.props.triggeringEvent] = this._handleTabChange.bind( this, - tab.name, - ); - return ( -
  • -
    - {icon} - {tab.tabContent} -
    - {closeButton} -
  • - ); - }); - return
      {tabs}
    ; - }; - - render(): React.Node { - return
    {this._renderTabMenu()}
    ; - } -} + tab.name); + + return ( + _react.createElement('li', Object.assign({ + className: (0, (_classnames || _load_classnames()).default)({ + tab: true, + active: this.props.activeTabName === tab.name }), + + key: tab.name }, + handler), + _react.createElement('div', { className: 'title' }, + icon, + tab.tabContent), + + closeButton)); + + + }); + return _react.createElement('ul', { className: 'tab-bar list-inline inset-panel' }, tabs); + }, _temp;} + + render() { + return _react.createElement('div', { className: 'nuclide-tabs' }, this._renderTabMenu()); + }}exports.default = Tabs; /** + * 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. + * + * + * @format + */Tabs.defaultProps = { closeable: false, triggeringEvent: 'onClick' }; \ No newline at end of file diff --git a/modules/nuclide-commons-ui/TextEditorBanner.js b/modules/nuclide-commons-ui/TextEditorBanner.js index 226afec4..ab34ba9f 100644 --- a/modules/nuclide-commons-ui/TextEditorBanner.js +++ b/modules/nuclide-commons-ui/TextEditorBanner.js @@ -1,69 +1,69 @@ -/** - * 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 - * @format - */ - -import type {AtomTextEditor} from './AtomTextEditor'; -import type {MessageType} from './Message'; -import {Message} from './Message'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import invariant from 'assert'; - -export class TextEditorBanner { - _disposables: UniversalDisposable; - _editor: atom$TextEditor | AtomTextEditor; - _element: HTMLElement; - _editorElement: HTMLElement; - _marker: ?atom$Marker; - - constructor(editor: atom$TextEditor | AtomTextEditor) { +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.Notice = exports.TextEditorBanner = undefined;var _Message; + + + + + + + + + + + + + +function _load_Message() {return _Message = require('./Message');}var _UniversalDisposable; + +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));} +var _react = _interopRequireWildcard(require('react')); +var _reactDom = _interopRequireDefault(require('react-dom'));function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */class TextEditorBanner {constructor(editor) { this._editor = editor; const editorElement = editor.getElement().firstChild; this._element = document.createElement('div'); - this._element.className = 'nuclide-ui-text-editor-banner-container'; + this._element.className = 'nuclide-ui-text-editor-banner-container';if (!( + + + editorElement instanceof HTMLElement && editorElement.parentNode != null)) {throw new Error('Invariant violation: "editorElement instanceof HTMLElement && editorElement.parentNode != null"');} - invariant( - editorElement instanceof HTMLElement && editorElement.parentNode != null, - ); editorElement.parentNode.insertBefore(this._element, editorElement); this._editorElement = editorElement; - this._disposables = new UniversalDisposable( - () => { - ReactDOM.unmountComponentAtNode(this._element); - this._element.replaceWith(editorElement); - }, - atom.workspace.observeActiveTextEditor(activeEditor => { - if (activeEditor == null) { - return; - } - if (activeEditor.getElement().contains(editor.getElement())) { - // This is needed for situations where the editor was rendered while - // display: none so _updateTextEditorElement wasn't able to properly - // measure at that time. - editor.getElement().measureDimensions(); - } - }), - ); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default( + () => { + _reactDom.default.unmountComponentAtNode(this._element); + this._element.replaceWith(editorElement); + }, + atom.workspace.observeActiveTextEditor(activeEditor => { + if (activeEditor == null) { + return; + } + if (activeEditor.getElement().contains(editor.getElement())) { + // This is needed for situations where the editor was rendered while + // display: none so _updateTextEditorElement wasn't able to properly + // measure at that time. + editor.getElement().measureDimensions(); + } + })); + } - dispose(): void { + dispose() { this._disposables.dispose(); } - _updateTextEditorElement(editorContainerRef: ?React.ElementRef<'div'>) { - const editorContainerNode = ReactDOM.findDOMNode(editorContainerRef); + _updateTextEditorElement(editorContainerRef) { + const editorContainerNode = _reactDom.default.findDOMNode(editorContainerRef); if (editorContainerNode == null) { return; } @@ -79,48 +79,47 @@ export class TextEditorBanner { // Fix for Hyperclicking a read-only file. // Restore the scroll position in the editor. - this._editor - .getElement() - .getModel() - .scrollToCursorPosition(); + this._editor. + getElement(). + getModel(). + scrollToCursorPosition(); } - render(reactElement: React.Element) { - ReactDOM.render( -
    -
    - {reactElement} -
    -
    this._updateTextEditorElement(ref)} - className="nuclide-ui-text-editor-banner-editor" - /> -
    , - this._element, - ); + render(reactElement) { + _reactDom.default.render( + _react.createElement('div', { className: 'nuclide-ui-text-editor-banner' }, + _react.createElement('div', { className: 'nuclide-ui-text-editor-banner-element' }, + reactElement), + + _react.createElement('div', { + // eslint-disable-next-line rulesdir/jsx-simple-callback-refs + ref: ref => this._updateTextEditorElement(ref), + className: 'nuclide-ui-text-editor-banner-editor' })), + + + this._element); + } hide() { this.dispose(); - } -} + }}exports.TextEditorBanner = TextEditorBanner; + + -type NoticeProps = { - messageType: MessageType, - children: React.Node, -}; -export class Notice extends React.Component { + + + +class Notice extends _react.Component { render() { return ( -
    - -
    - {this.props.children} -
    -
    -
    - ); - } -} + _react.createElement('div', { className: 'nuclide-ui-text-editor-banner-notice' }, + _react.createElement((_Message || _load_Message()).Message, { type: this.props.messageType }, + _react.createElement('div', { className: 'nuclide-ui-text-editor-banner-notice-content' }, + this.props.children)))); + + + + + }}exports.Notice = Notice; \ No newline at end of file diff --git a/modules/nuclide-commons-ui/TextInputs.example.js b/modules/nuclide-commons-ui/TextInputs.example.js index 466153f3..9e1f1918 100644 --- a/modules/nuclide-commons-ui/TextInputs.example.js +++ b/modules/nuclide-commons-ui/TextInputs.example.js @@ -1,125 +1,122 @@ -/** - * 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 - * @format - */ - -import {TextBuffer} from 'atom'; -import * as React from 'react'; -import {Block} from './Block'; -import {AtomInput} from './AtomInput'; -import {AtomTextEditor} from './AtomTextEditor'; - -const AtomInputExample = (): React.Element => ( -
    - - - - - - - - - - - - - - - - - - - - - -
    -); - -const buffer1 = new TextBuffer({ - text: '/**\n * Hi!\n */\n\n// I am a TextBuffer.\nconst a = 42;', -}); -const buffer2 = new TextBuffer({ - text: - '/**\n * Hi!\n */\n\n// I am a read-only, gutter-less TextBuffer.\nconst a = 42;', -}); +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.TextInputExamples = undefined; + + + + + + + + + + + +var _atom = require('atom'); +var _react = _interopRequireWildcard(require('react'));var _Block; +function _load_Block() {return _Block = require('./Block');}var _AtomInput; +function _load_AtomInput() {return _AtomInput = require('./AtomInput');}var _AtomTextEditor; +function _load_AtomTextEditor() {return _AtomTextEditor = require('./AtomTextEditor');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} + +const AtomInputExample = () => +_react.createElement('div', null, + _react.createElement((_Block || _load_Block()).Block, null, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + disabled: false, + initialValue: 'atom input', + placeholderText: 'placeholder text' })), + + + _react.createElement((_Block || _load_Block()).Block, null, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + disabled: true, + initialValue: 'disabled atom input', + placeholderText: 'placeholder text' })), + + + _react.createElement((_Block || _load_Block()).Block, null, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + initialValue: 'xs atom input', + placeholderText: 'placeholder text', + size: 'xs' })), + + + _react.createElement((_Block || _load_Block()).Block, null, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + initialValue: 'sm atom input', + placeholderText: 'placeholder text', + size: 'sm' })), + + + _react.createElement((_Block || _load_Block()).Block, null, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + initialValue: 'lg atom input', + placeholderText: 'placeholder text', + size: 'lg' })), + + + _react.createElement((_Block || _load_Block()).Block, null, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + initialValue: 'unstyled atom input', + placeholderText: 'placeholder text', + unstyled: true })), + + + _react.createElement((_Block || _load_Block()).Block, null, + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + initialValue: 'atom input with custom width', + placeholderText: 'placeholder text', + width: 200 }))); /** + * 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. + * + * + * @format + */const buffer1 = new _atom.TextBuffer({ text: '/**\n * Hi!\n */\n\n// I am a TextBuffer.\nconst a = 42;' });const buffer2 = new _atom.TextBuffer({ text: + '/**\n * Hi!\n */\n\n// I am a read-only, gutter-less TextBuffer.\nconst a = 42;' }); + const editorWrapperStyle = { display: 'flex', flexGrow: 1, height: '12em', - boxShadow: '0 0 20px 0 rgba(0, 0, 0, 0.3)', -}; - -const AtomTextEditorExample = (): React.Element => ( - -
    - -
    -
    - -
    -
    -); - -export const TextInputExamples = { + boxShadow: '0 0 20px 0 rgba(0, 0, 0, 0.3)' }; + + +const AtomTextEditorExample = () => +_react.createElement((_Block || _load_Block()).Block, null, + _react.createElement('div', { style: editorWrapperStyle }, + _react.createElement((_AtomTextEditor || _load_AtomTextEditor()).AtomTextEditor, { + gutterHidden: false, + readOnly: false, + syncTextContents: false, + autoGrow: false, + path: 'aJavaScriptFile.js', + textBuffer: buffer1 })), + + + _react.createElement('div', { style: Object.assign({}, editorWrapperStyle, { marginTop: '2em' }) }, + _react.createElement((_AtomTextEditor || _load_AtomTextEditor()).AtomTextEditor, { + gutterHidden: true, + readOnly: true, + syncTextContents: false, + autoGrow: false, + path: 'aJavaScriptFile.js', + textBuffer: buffer2 }))); + + + + + +const TextInputExamples = exports.TextInputExamples = { sectionName: 'Text Inputs', description: '', examples: [ - { - title: 'AtomInput', - component: AtomInputExample, - }, - { - title: 'AtomTextEditor', - component: AtomTextEditorExample, - }, - ], -}; + { + title: 'AtomInput', + component: AtomInputExample }, + + { + title: 'AtomTextEditor', + component: AtomTextEditorExample }] }; \ No newline at end of file diff --git a/modules/nuclide-commons-ui/TextRenderer.js b/modules/nuclide-commons-ui/TextRenderer.js index 2a33a4ca..38fdc207 100644 --- a/modules/nuclide-commons-ui/TextRenderer.js +++ b/modules/nuclide-commons-ui/TextRenderer.js @@ -1,35 +1,45 @@ -/** - * 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 - * @format - */ - -import * as React from 'react'; - -/* Evaluation & values */ -export type EvaluationResult = { - type: string, - // Either: - value?: string, - // Or: - description?: string, - objectId?: string, - subtype?: string, -}; - -export function TextRenderer( - evaluationResult: EvaluationResult, -): ?React.Element { - const {type, value} = evaluationResult; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + + + + + + + + + + + + +TextRenderer = TextRenderer;var _react = _interopRequireWildcard(require('react'));function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} /* Evaluation & values */function TextRenderer( +evaluationResult) +{ + const { type, value } = evaluationResult; if (type === 'text') { - return {value}; + return _react.createElement('span', null, value); } else { return null; } -} +} /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons-ui/Toggle.js b/modules/nuclide-commons-ui/Toggle.js index c95516af..0a541d53 100644 --- a/modules/nuclide-commons-ui/Toggle.js +++ b/modules/nuclide-commons-ui/Toggle.js @@ -1,70 +1,79 @@ -/** - * 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 - * @format - */ - -import * as React from 'react'; -import classnames from 'classnames'; - -import ignoreTextSelectionEvents from './ignoreTextSelectionEvents'; - -type DefaultProps = { - disabled: boolean, - onClick: (event: SyntheticEvent<>) => mixed, -}; - -type Props = { - className?: string, - toggled: boolean, - disabled: boolean, - label: ?string, - onChange: (isToggled: boolean) => mixed, - onClick: (event: SyntheticEvent<>) => mixed, -}; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.Toggle = undefined; + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react'));var _classnames; +function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));}var _ignoreTextSelectionEvents; + +function _load_ignoreTextSelectionEvents() {return _ignoreTextSelectionEvents = _interopRequireDefault(require('./ignoreTextSelectionEvents'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} + + + + + + + + + + + + + + /** - * A toggle component with an input toggle and a label. We restrict the label to a string - * to ensure this component is pure. - */ -export class Toggle extends React.Component { - static defaultProps: DefaultProps = { - disabled: false, - onClick(event) {}, - }; - - _onChange = (event: SyntheticEvent<>) => { - const isToggled = ((event.target: any): HTMLInputElement).checked; - this.props.onChange.call(null, isToggled); - }; - - render(): React.Node { - const {className, disabled, label, onClick, toggled} = this.props; + * A toggle component with an input toggle and a label. We restrict the label to a string + * to ensure this component is pure. + */ +class Toggle extends _react.Component {constructor(...args) {var _temp;return _temp = super(...args), this. + + + + + + _onChange = event => { + const isToggled = event.target.checked; + this.props.onChange.call(null, isToggled); + }, _temp;} + + render() { + const { className, disabled, label, onClick, toggled } = this.props; const text = - label === '' ? null : ( - {label} - ); + label === '' ? null : + _react.createElement('span', { className: 'nuclide-ui-toggle-label-text' }, ' ', label); + return ( - - ); - } -} + _react.createElement('label', { + className: (0, (_classnames || _load_classnames()).default)(className, 'nuclide-ui-toggle-label', { + 'nuclide-ui-toggle-disabled': disabled }), + + onClick: onClick && (0, (_ignoreTextSelectionEvents || _load_ignoreTextSelectionEvents()).default)(onClick) }, + _react.createElement('input', { + checked: toggled, + className: 'input-toggle', + disabled: disabled, + onChange: this._onChange, + type: 'checkbox' }), + + text)); + + + }}exports.Toggle = Toggle; /** + * 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. + * + * + * @format + */Toggle.defaultProps = { disabled: false, onClick(event) {} }; \ No newline at end of file diff --git a/modules/nuclide-commons-ui/Toolbar.example.js b/modules/nuclide-commons-ui/Toolbar.example.js index f8093874..5ca9e2bf 100644 --- a/modules/nuclide-commons-ui/Toolbar.example.js +++ b/modules/nuclide-commons-ui/Toolbar.example.js @@ -1,97 +1,94 @@ -/** - * 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 - * @format - */ - -import * as React from 'react'; -import {Block} from './Block'; -import {Toolbar} from './Toolbar'; -import {ToolbarCenter} from './ToolbarCenter'; -import {ToolbarLeft} from './ToolbarLeft'; -import {ToolbarRight} from './ToolbarRight'; -import {Button} from './Button'; - -const ToolbarExampleLeft = (): React.Element => ( -
    - - - -
    a toolbar can have multiple children,
    - -
    -
    -
    - -
    - Be sure to use {', , and '} as - children. -
    -
    -
    -); - -const ToolbarExampleCenter = (): React.Element => ( - - - -
    Example of {''}.
    -
    -
    -
    -); - -const ToolbarExampleRight = (): React.Element => ( - - - -
    Example of {''}
    -
    -
    -
    -); - -const ToolbarExampleMultiple = (): React.Element => ( - - - -
    You can combine
    -
    - -
    the various kinds
    -
    - -
    of aligners.
    -
    -
    -
    -); - -export const ToolbarExamples = { +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.ToolbarExamples = undefined; + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react'));var _Block; +function _load_Block() {return _Block = require('./Block');}var _Toolbar; +function _load_Toolbar() {return _Toolbar = require('./Toolbar');}var _ToolbarCenter; +function _load_ToolbarCenter() {return _ToolbarCenter = require('./ToolbarCenter');}var _ToolbarLeft; +function _load_ToolbarLeft() {return _ToolbarLeft = require('./ToolbarLeft');}var _ToolbarRight; +function _load_ToolbarRight() {return _ToolbarRight = require('./ToolbarRight');}var _Button; +function _load_Button() {return _Button = require('./Button');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} + +const ToolbarExampleLeft = () => +_react.createElement('div', null, + _react.createElement((_Block || _load_Block()).Block, null, + _react.createElement((_Toolbar || _load_Toolbar()).Toolbar, { location: 'top' }, + _react.createElement((_ToolbarLeft || _load_ToolbarLeft()).ToolbarLeft, null, + _react.createElement('div', null, 'a toolbar can have multiple children,'), + _react.createElement((_Button || _load_Button()).Button, null, 'such as this button.')))), + + + + _react.createElement((_Block || _load_Block()).Block, null, + _react.createElement('div', null, 'Be sure to use ', + ', , and ', ' as children.'))); /** + * 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. + * + * + * @format + */const ToolbarExampleCenter = () => _react.createElement((_Block || _load_Block()).Block, null, _react.createElement((_Toolbar || _load_Toolbar()).Toolbar, { location: 'top' }, _react.createElement((_ToolbarCenter || _load_ToolbarCenter()).ToolbarCenter, null, + _react.createElement('div', null, 'Example of ', '', '.')))); + + + + + +const ToolbarExampleRight = () => +_react.createElement((_Block || _load_Block()).Block, null, + _react.createElement((_Toolbar || _load_Toolbar()).Toolbar, { location: 'top' }, + _react.createElement((_ToolbarRight || _load_ToolbarRight()).ToolbarRight, null, + _react.createElement('div', null, 'Example of ', '')))); + + + + + +const ToolbarExampleMultiple = () => +_react.createElement((_Block || _load_Block()).Block, null, + _react.createElement((_Toolbar || _load_Toolbar()).Toolbar, { location: 'top' }, + _react.createElement((_ToolbarLeft || _load_ToolbarLeft()).ToolbarLeft, null, + _react.createElement('div', null, 'You can combine')), + + _react.createElement((_ToolbarCenter || _load_ToolbarCenter()).ToolbarCenter, null, + _react.createElement('div', null, 'the various kinds')), + + _react.createElement((_ToolbarRight || _load_ToolbarRight()).ToolbarRight, null, + _react.createElement('div', null, 'of aligners.')))); + + + + + +const ToolbarExamples = exports.ToolbarExamples = { sectionName: 'Toolbar', description: '', examples: [ - { - title: 'Left Toolbar', - component: ToolbarExampleLeft, - }, - { - title: 'Center Toolbar', - component: ToolbarExampleCenter, - }, - { - title: 'Right Toolbar', - component: ToolbarExampleRight, - }, - { - title: 'Combining Toolbar aligners', - component: ToolbarExampleMultiple, - }, - ], -}; + { + title: 'Left Toolbar', + component: ToolbarExampleLeft }, + + { + title: 'Center Toolbar', + component: ToolbarExampleCenter }, + + { + title: 'Right Toolbar', + component: ToolbarExampleRight }, + + { + title: 'Combining Toolbar aligners', + component: ToolbarExampleMultiple }] }; \ No newline at end of file diff --git a/modules/nuclide-commons-ui/Toolbar.js b/modules/nuclide-commons-ui/Toolbar.js index 8c1579c3..05f969a8 100644 --- a/modules/nuclide-commons-ui/Toolbar.js +++ b/modules/nuclide-commons-ui/Toolbar.js @@ -1,37 +1,47 @@ -/** - * 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 - * @format - */ - -import classnames from 'classnames'; -import * as React from 'react'; -import {maybeToString} from 'nuclide-commons/string'; - -type Props = { - children?: mixed, - className?: string, - location?: 'top' | 'bottom', -}; - -export const Toolbar = (props: Props) => { - const className = classnames( - 'nuclide-ui-toolbar', - { - [`nuclide-ui-toolbar--${maybeToString(props.location)}`]: - props.location != null, - }, - props.className, - ); +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.Toolbar = undefined;var _classnames; + + + + + + + + + + + +function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));} +var _react = _interopRequireWildcard(require('react'));var _string; +function _load_string() {return _string = require('nuclide-commons/string');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + + + + + + + +const Toolbar = exports.Toolbar = props => { + const className = (0, (_classnames || _load_classnames()).default)( + 'nuclide-ui-toolbar', + { + [`nuclide-ui-toolbar--${(0, (_string || _load_string()).maybeToString)(props.location)}`]: + props.location != null }, + + props.className); + return ( // $FlowFixMe(>=0.53.0) Flow suppress -
    {props.children}
    - ); -}; + _react.createElement('div', { className: className }, props.children)); + +}; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons-ui/ToolbarCenter.js b/modules/nuclide-commons-ui/ToolbarCenter.js index 757092d8..0c3d675d 100644 --- a/modules/nuclide-commons-ui/ToolbarCenter.js +++ b/modules/nuclide-commons-ui/ToolbarCenter.js @@ -1,24 +1,34 @@ -/** - * 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 - * @format - */ - -import * as React from 'react'; - -type Props = { - children?: mixed, -}; - -export const ToolbarCenter = (props: Props) => { +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.ToolbarCenter = undefined; + + + + + + + + + + + +var _react = _interopRequireWildcard(require("react"));function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} + + + + + +const ToolbarCenter = exports.ToolbarCenter = props => { return ( // $FlowFixMe(>=0.53.0) Flow suppress -
    {props.children}
    - ); -}; + _react.createElement("div", { className: "nuclide-ui-toolbar__center" }, props.children)); + +}; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons-ui/ToolbarLeft.js b/modules/nuclide-commons-ui/ToolbarLeft.js index 47b489cb..6220220a 100644 --- a/modules/nuclide-commons-ui/ToolbarLeft.js +++ b/modules/nuclide-commons-ui/ToolbarLeft.js @@ -1,24 +1,34 @@ -/** - * 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 - * @format - */ - -import * as React from 'react'; - -type Props = { - children?: mixed, -}; - -export const ToolbarLeft = (props: Props) => { +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.ToolbarLeft = undefined; + + + + + + + + + + + +var _react = _interopRequireWildcard(require("react"));function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} + + + + + +const ToolbarLeft = exports.ToolbarLeft = props => { return ( // $FlowFixMe(>=0.53.0) Flow suppress -
    {props.children}
    - ); -}; + _react.createElement("div", { className: "nuclide-ui-toolbar__left" }, props.children)); + +}; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons-ui/ToolbarRight.js b/modules/nuclide-commons-ui/ToolbarRight.js index 1f6af83e..5dab0604 100644 --- a/modules/nuclide-commons-ui/ToolbarRight.js +++ b/modules/nuclide-commons-ui/ToolbarRight.js @@ -1,24 +1,34 @@ -/** - * 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 - * @format - */ - -import * as React from 'react'; - -type Props = { - children?: mixed, -}; - -export const ToolbarRight = (props: Props) => { +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.ToolbarRight = undefined; + + + + + + + + + + + +var _react = _interopRequireWildcard(require("react"));function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} + + + + + +const ToolbarRight = exports.ToolbarRight = props => { return ( // $FlowFixMe(>=0.53.0) Flow suppress -
    {props.children}
    - ); -}; + _react.createElement("div", { className: "nuclide-ui-toolbar__right" }, props.children)); + +}; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons-ui/ToolbarUtils.js b/modules/nuclide-commons-ui/ToolbarUtils.js index a96402c6..8558ac1c 100644 --- a/modules/nuclide-commons-ui/ToolbarUtils.js +++ b/modules/nuclide-commons-ui/ToolbarUtils.js @@ -1,32 +1,42 @@ -/** - * 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 - * @format - */ - -import humanizeKeystroke from 'nuclide-commons/humanizeKeystroke'; - -export function makeToolbarButtonSpec( - options: toolbar$ButtonSpec, -): toolbar$ButtonSpec { +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + +makeToolbarButtonSpec = makeToolbarButtonSpec;var _humanizeKeystroke;function _load_humanizeKeystroke() {return _humanizeKeystroke = _interopRequireDefault(require('nuclide-commons/humanizeKeystroke'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function makeToolbarButtonSpec( +options) +{ const command = options.callback; if (typeof command === 'string') { const [keyBinding] = atom.keymaps.findKeyBindings({ command, - target: atom.views.getView(atom.workspace), - }); + target: atom.views.getView(atom.workspace) }); + const tooltipStr = options.tooltip; if (keyBinding != null && tooltipStr != null) { - const keyString = humanizeKeystroke(keyBinding.keystrokes, null); + const keyString = (0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)(keyBinding.keystrokes, null); options.tooltip = `${tooltipStr} (${keyString})`; } } - return {...options}; -} + return Object.assign({}, options); +} /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons-ui/Tree.example.js b/modules/nuclide-commons-ui/Tree.example.js index 88a41a26..bfaab280 100644 --- a/modules/nuclide-commons-ui/Tree.example.js +++ b/modules/nuclide-commons-ui/Tree.example.js @@ -1,94 +1,94 @@ -/** - * 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 - * @format - */ - -import * as React from 'react'; -import {Block} from './Block'; -import {Icon} from './Icon'; -import {TreeList, TreeItem, NestedTreeItem} from './Tree'; - -const BasicTreeExample = (): React.Element => ( -
    - Trees - - - TreeItem 1 - TreeItem 2 - NestedTreeItem 1 -- click me!} - onSelect={handleSelect} - onConfirm={handleConfirm} - onTripleClick={handleTripleClick} - selected={true}> - TreeItem 3 - TreeItem 4 - - NestedTreeItem 2} - collapsed={true} - /> - - -
    -); - -const AtomStyleguideTreeExample = (): React.Element => ( - - - A Directory}> - Nested Directory}> - - File one - - - Collapsed Nested Directory}> - - File one - - - - File one - - - File three .selected! - - - - .icon-file-text - - - .icon-file-symlink-file - - - -); - -export const TreeExamples = { +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.TreeExamples = undefined; + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react'));var _Block; +function _load_Block() {return _Block = require('./Block');}var _Icon; +function _load_Icon() {return _Icon = require('./Icon');}var _Tree; +function _load_Tree() {return _Tree = require('./Tree');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} /** + * 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. + * + * + * @format + */const BasicTreeExample = () => _react.createElement('div', null, 'Trees', _react.createElement((_Block || _load_Block()).Block, null, _react.createElement((_Tree || _load_Tree()).TreeList, null, _react.createElement((_Tree || _load_Tree()).TreeItem, null, 'TreeItem 1'), _react.createElement((_Tree || _load_Tree()).TreeItem, null, 'TreeItem 2'), _react.createElement((_Tree || _load_Tree()).NestedTreeItem, { title: _react.createElement('span', null, 'NestedTreeItem 1 -- click me!'), + onSelect: handleSelect, + onConfirm: handleConfirm, + onTripleClick: handleTripleClick, + selected: true }, + _react.createElement((_Tree || _load_Tree()).TreeItem, null, 'TreeItem 3'), + _react.createElement((_Tree || _load_Tree()).TreeItem, null, 'TreeItem 4')), + + _react.createElement((_Tree || _load_Tree()).NestedTreeItem, { + title: _react.createElement('span', null, 'NestedTreeItem 2'), + collapsed: true })))); + + + + + + +const AtomStyleguideTreeExample = () => +_react.createElement((_Block || _load_Block()).Block, null, + _react.createElement((_Tree || _load_Tree()).TreeList, { showArrows: true }, + _react.createElement((_Tree || _load_Tree()).NestedTreeItem, { title: _react.createElement((_Icon || _load_Icon()).Icon, { icon: 'file-directory' }, 'A Directory') }, + _react.createElement((_Tree || _load_Tree()).NestedTreeItem, { + collapsed: false, + title: _react.createElement((_Icon || _load_Icon()).Icon, { icon: 'file-directory' }, 'Nested Directory') }, + _react.createElement((_Tree || _load_Tree()).TreeItem, null, + _react.createElement((_Icon || _load_Icon()).Icon, { icon: 'file-text' }, 'File one'))), + + + _react.createElement((_Tree || _load_Tree()).NestedTreeItem, { + collapsed: true, + title: _react.createElement((_Icon || _load_Icon()).Icon, { icon: 'file-directory' }, 'Collapsed Nested Directory') }, + _react.createElement((_Tree || _load_Tree()).TreeItem, null, + _react.createElement((_Icon || _load_Icon()).Icon, { icon: 'file-text' }, 'File one'))), + + + _react.createElement((_Tree || _load_Tree()).TreeItem, null, + _react.createElement((_Icon || _load_Icon()).Icon, { icon: 'file-text' }, 'File one')), + + _react.createElement((_Tree || _load_Tree()).TreeItem, { selected: true }, + _react.createElement((_Icon || _load_Icon()).Icon, { icon: 'file-text' }, 'File three .selected!'))), + + + _react.createElement((_Tree || _load_Tree()).TreeItem, null, + _react.createElement((_Icon || _load_Icon()).Icon, { icon: 'file-text' }, '.icon-file-text')), + + _react.createElement((_Tree || _load_Tree()).TreeItem, null, + _react.createElement((_Icon || _load_Icon()).Icon, { icon: 'file-symlink-file' }, '.icon-file-symlink-file')))); + + + + + +const TreeExamples = exports.TreeExamples = { sectionName: 'Trees', description: 'Expandable, hierarchical lists.', examples: [ - { - title: 'Basic Tree', - component: BasicTreeExample, - }, - { - title: 'Reproducing the Atom style guide example:', - component: AtomStyleguideTreeExample, - }, - ], -}; + { + title: 'Basic Tree', + component: BasicTreeExample }, + + { + title: 'Reproducing the Atom style guide example:', + component: AtomStyleguideTreeExample }] }; + + + function handleSelect() { atom.notifications.addInfo('selected!'); @@ -98,4 +98,4 @@ function handleConfirm() { } function handleTripleClick() { atom.notifications.addInfo('triple clicked!'); -} +} \ No newline at end of file diff --git a/modules/nuclide-commons-ui/Tree.js b/modules/nuclide-commons-ui/Tree.js index 5db9e9db..a5bc5aba 100644 --- a/modules/nuclide-commons-ui/Tree.js +++ b/modules/nuclide-commons-ui/Tree.js @@ -1,57 +1,57 @@ -/** - * 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 - * @format - */ - -/* eslint-env browser */ - -import * as React from 'react'; -import classnames from 'classnames'; -import invariant from 'assert'; -import {scrollIntoView} from './scrollIntoView'; - -export function Tree({className, style, ...props}: Object) { - return ( -
      - ); -} - -type TreeItemProps = {| - children?: React.Node, - className?: string, - // handled below in `handleClick` - /* eslint-disable react/no-unused-prop-types */ - onSelect?: (e: SyntheticMouseEvent<>) => mixed, - onConfirm?: (e: SyntheticMouseEvent<>) => mixed, - onTripleClick?: (e: SyntheticMouseEvent<>) => mixed, - /* eslint-enable react/no-unused-prop-types */ - selected?: boolean, - onMouseDown?: (e: SyntheticMouseEvent<>) => mixed, - onMouseEnter?: (e: SyntheticMouseEvent<>) => mixed, - onMouseLeave?: (e: SyntheticMouseEvent<>) => mixed, - path?: string, - name?: string, -|}; - -export class TreeItem extends React.Component { - _liNode: ?HTMLLIElement; - _handleClick = handleClick.bind(this); +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.TreeList = exports.NestedTreeItem = exports.TreeItem = undefined;exports. + + + + + + + + + + + + + + + + + + +Tree = Tree;var _react = _interopRequireWildcard(require('react'));var _classnames;function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));}var _scrollIntoView;function _load_scrollIntoView() {return _scrollIntoView = require('./scrollIntoView');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _objectWithoutProperties(obj, keys) {var target = {};for (var i in obj) {if (keys.indexOf(i) >= 0) continue;if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;target[i] = obj[i];}return target;} /** + * 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. + * + * + * @format + */ /* eslint-env browser */function Tree(_ref) {let { className, style } = _ref,props = _objectWithoutProperties(_ref, ['className', 'style']);return _react.createElement('ol', Object.assign({ className: (0, (_classnames || _load_classnames()).default)('list-tree', className), role: 'tree', style: Object.assign({ position: 'relative' }, style) }, props));} + + + + + + + + + + + + + + + + + +class TreeItem extends _react.Component {constructor(...args) {var _temp;return _temp = super(...args), this. + + _handleClick = handleClick.bind(this), _temp;} scrollIntoView() { if (this._liNode != null) { - scrollIntoView(this._liNode); + (0, (_scrollIntoView || _load_scrollIntoView()).scrollIntoView)(this._liNode); } } @@ -64,67 +64,67 @@ export class TreeItem extends React.Component { onMouseEnter, onMouseLeave, path, - name, - } = this.props; + name } = + this.props; return ( -
    1. (this._liNode = liNode)} - role="treeitem" - tabIndex={selected ? '0' : '-1'}> - {selected && typeof children === 'string' ? ( - // String children must be wrapped to receive correct styles when selected. - {children} - ) : ( - children - )} -
    2. - ); - } -} - -type NestedTreeItemProps = {| - title?: React.Node, - children?: mixed, - className?: string, - hasFlatChildren?: boolean, // passthrough to inner TreeList - selected?: boolean, - collapsed?: boolean, - // handled below in `handleClick` - /* eslint-disable react/no-unused-prop-types */ - onSelect?: (e: SyntheticMouseEvent<>) => mixed, - onConfirm?: (e: SyntheticMouseEvent<>) => mixed, - onTripleClick?: (e: SyntheticMouseEvent<>) => mixed, - /* eslint-disable react/no-unused-prop-types */ -|}; - -export class NestedTreeItem extends React.Component { - _itemNode: ?HTMLDivElement; - _handleClick = (e: SyntheticMouseEvent<>) => { - const itemNode = this._itemNode; - if (itemNode == null) { - return; - } + selected }, - invariant(e.target instanceof Element); - if (e.target.closest('.list-item') === itemNode) { - handleClick.call(this, e); - } - }; + 'list-item'), + + onMouseDown: onMouseDown, + onMouseEnter: onMouseEnter, + onMouseLeave: onMouseLeave, + 'data-path': path, + 'data-name': name, + onClick: this._handleClick, + ref: liNode => this._liNode = liNode, + role: 'treeitem', + tabIndex: selected ? '0' : '-1' }, + selected && typeof children === 'string' ? + // String children must be wrapped to receive correct styles when selected. + _react.createElement('span', null, children) : + + children)); + + + + }}exports.TreeItem = TreeItem; + + + + + + + + + + + + + + + + + +class NestedTreeItem extends _react.Component {constructor(...args) {var _temp2;return _temp2 = super(...args), this. + + _handleClick = e => { + const itemNode = this._itemNode; + if (itemNode == null) { + return; + }if (!( + + e.target instanceof Element)) {throw new Error('Invariant violation: "e.target instanceof Element"');} + if (e.target.closest('.list-item') === itemNode) { + handleClick.call(this, e); + } + }, _temp2;} render() { const { @@ -133,63 +133,63 @@ export class NestedTreeItem extends React.Component { selected, collapsed, title, - children, - } = this.props; + children } = + this.props; return ( -
    3. - {title == null ? null : ( -
      (this._itemNode = node)}> - {title} -
      - )} - {children} -
    4. - ); - } -} - -type TreeListProps = { - className?: string, - /* typically, instances of TreeItem or NestedTreeItem. */ - children?: mixed, - showArrows?: boolean, - hasFlatChildren?: boolean, -}; -export const TreeList = (props: TreeListProps) => ( - // $FlowFixMe(>=0.53.0) Flow suppress -
        - {props.children} -
      -); - -function handleClick(e: SyntheticMouseEvent<>): void { - const {onSelect, onConfirm, onTripleClick} = this.props; + collapsed }, + + 'list-nested-item'), + + onClick: this._handleClick, + role: 'treeitem', + tabIndex: selected ? '0' : '-1' }, + title == null ? null : + _react.createElement('div', { + tabIndex: -1, + className: 'native-key-bindings list-item', + ref: node => this._itemNode = node }, + title), + + + _react.createElement(TreeList, { hasFlatChildren: hasFlatChildren }, children))); + + + }}exports.NestedTreeItem = NestedTreeItem; + + + + + + + + + +const TreeList = exports.TreeList = props => +// $FlowFixMe(>=0.53.0) Flow suppress +_react.createElement('ul', { + className: (0, (_classnames || _load_classnames()).default)( + props.className, + { + 'has-collapsable-children': props.showArrows, + 'has-flat-children': props.hasFlatChildren }, + + 'list-tree'), + + role: 'group' }, + props.children); + + + +function handleClick(e) { + const { onSelect, onConfirm, onTripleClick } = this.props; const numberOfClicks = e.detail; switch (numberOfClicks) { @@ -203,6 +203,6 @@ function handleClick(e: SyntheticMouseEvent<>): void { onTripleClick && onTripleClick(e); break; default: - break; - } -} + break;} + +} \ No newline at end of file diff --git a/modules/nuclide-commons-ui/TruncatedButton.js b/modules/nuclide-commons-ui/TruncatedButton.js index 1f0e7a23..83887847 100644 --- a/modules/nuclide-commons-ui/TruncatedButton.js +++ b/modules/nuclide-commons-ui/TruncatedButton.js @@ -1,40 +1,39 @@ -/** - * 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 - * @format - */ - -import {Button} from './Button'; -import classnames from 'classnames'; -import * as React from 'react'; - -type Props = { - className?: string, - // $FlowFixMe(>=0.53.0) Flow suppress - children?: React.Children, - label?: string, -}; - -export default class TruncatedButton extends React.Component { - render(): React.Node { - const {children, className, label, ...props} = this.props; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _Button; + + + + + + + + + + + +function _load_Button() {return _Button = require('./Button');}var _classnames; +function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));} +var _react = _interopRequireWildcard(require('react'));function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _objectWithoutProperties(obj, keys) {var target = {};for (var i in obj) {if (keys.indexOf(i) >= 0) continue;if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;target[i] = obj[i];}return target;} /** + * 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. + * + * + * @format + */class TruncatedButton extends _react.Component {render() { + const _props = this.props,{ children, className, label } = _props,props = _objectWithoutProperties(_props, ['children', 'className', 'label']); return ( - - ); - } -} + className), + + title: label }, + props), + children || label)); + + + }}exports.default = TruncatedButton; \ No newline at end of file diff --git a/modules/nuclide-commons-ui/UnstyledButton.js b/modules/nuclide-commons-ui/UnstyledButton.js index ef54921a..acf73117 100644 --- a/modules/nuclide-commons-ui/UnstyledButton.js +++ b/modules/nuclide-commons-ui/UnstyledButton.js @@ -1,37 +1,36 @@ -/** - * 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 - * @format - */ - -import React from 'react'; -import classnames from 'classnames'; -import nullthrows from 'nullthrows'; - -type Props = { - className?: string, -}; - -export default class UnstyledButton extends React.Component { - props: Props; - _node: ?HTMLButtonElement; - - focus(): void { - nullthrows(this._node).focus(); - } - - _setRef = (node: ?HTMLButtonElement) => (this._node = node); - - render(): React$Element { - const {className, ...props} = this.props; - const classes = classnames('nuclide-ui-unstyled-button', className); +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); + + + + + + + + + + + +var _react = _interopRequireDefault(require('react'));var _classnames; +function _load_classnames() {return _classnames = _interopRequireDefault(require('classnames'));}var _nullthrows; +function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _objectWithoutProperties(obj, keys) {var target = {};for (var i in obj) {if (keys.indexOf(i) >= 0) continue;if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;target[i] = obj[i];}return target;} /** + * 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. + * + * + * @format + */class UnstyledButton extends _react.default.Component {constructor(...args) {var _temp;return _temp = super(...args), this. + + + + _setRef = node => this._node = node, _temp;}focus() {(0, (_nullthrows || _load_nullthrows()).default)(this._node).focus();} + + render() { + const _props = this.props,{ className } = _props,props = _objectWithoutProperties(_props, ['className']); + const classes = (0, (_classnames || _load_classnames()).default)('nuclide-ui-unstyled-button', className); // eslint-disable-next-line rulesdir/use-nuclide-ui-components - return ; -} + return _react.createElement((_Button || _load_Button()).Button, { onClick: showExampleModal }, 'Show Modal'); +} /** + * 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. + * + * + * @format + */function showExampleModal() {(0, (_showModal || _load_showModal()).default)(({ dismiss }) => {return _react.createElement('div', null, _react.createElement('div', null, 'I\'m a modal. You can add any content you like. I have all the standard behavior, like obeying the "core:cancel" command!'), _react.createElement((_Button || _load_Button()).Button, { onClick: dismiss }, 'Hide Modal')); + -function showExampleModal() { - showModal(({dismiss}) => { - return ( -
      -
      - I'm a modal. You can add any content you like. I have all the standard - behavior, like obeying the "core:cancel" command! -
      - -
      - ); }); } -export const ModalExamples = { +const ModalExamples = exports.ModalExamples = { sectionName: 'Modal', description: 'Overlays that cover the entire screen. ', examples: [ - { - title: 'Click the button to toggle a modal:', - component: ModalButton, - }, - ], -}; + { + title: 'Click the button to toggle a modal:', + component: ModalButton }] }; \ No newline at end of file diff --git a/modules/nuclide-commons-ui/showModal.js b/modules/nuclide-commons-ui/showModal.js index 26b42bd0..df875a31 100644 --- a/modules/nuclide-commons-ui/showModal.js +++ b/modules/nuclide-commons-ui/showModal.js @@ -1,160 +1,160 @@ -/** - * 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 - * @format - */ - -/* global Node */ -/* global HTMLElement */ - -import invariant from 'assert'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import {Observable} from 'rxjs'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; - -import TabbableContainer from './TabbableContainer'; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default = -/** - * Given a function to dismiss the modal, return a React element for the content. - * Call the function when e.g. the user clicks a Cancel or Submit button. - */ -type ContentFactory = ({ - dismiss(): void, - element: Element, -}) => React.Node; - -/** Wrap options in an object so we can add new ones later without an explosion of params */ -type Options = {| - /** Called when the modal is dismissed (just before it is destroyed). */ - onDismiss?: () => mixed, - onOpen?: () => mixed, - /** - * Called when the user clicks outside the modal, return false to prevent dismissal. - * If unspecified the modal will be dismissed if the user clicks outside the modal. - */ - shouldDismissOnClickOutsideModal?: () => boolean, - /** - * Called when the user presses the escape key, return false to prevent dismissal. - * If unspecified the modal will be dismissed if the user presses escape. - */ - shouldDismissOnPressEscape?: () => boolean, - /** Passed to atom's underlying addModalPanel function. */ - priority?: number, - /** Passed to atom's underlying addModalPanel function. */ - className?: string, -|}; -/** - * Shows a modal dialog that renders a React element as its content. - * The modal is automatically hidden when the user clicks outside of it, and on core:cancel (esc). - * The modal panel unmounts its React component and destroys the panel as soon as it is hidden; - * you may not hide the panel and then re-show it later. - * Returns a disposable that you may use to hide and destroy the modal. - */ -export default function showModal( - contentFactory: ContentFactory, - options: Options = defaults, -): IDisposable { - const hostElement = document.createElement('div'); - const atomPanel = atom.workspace.addModalPanel({ - item: hostElement, - priority: options.priority, - className: options.className, + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +showModal;var _react = _interopRequireWildcard(require('react'));var _reactDom = _interopRequireDefault(require('react-dom'));var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _UniversalDisposable;function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _TabbableContainer;function _load_TabbableContainer() {return _TabbableContainer = _interopRequireDefault(require('./TabbableContainer'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} /** + * Shows a modal dialog that renders a React element as its content. + * The modal is automatically hidden when the user clicks outside of it, and on core:cancel (esc). + * The modal panel unmounts its React component and destroys the panel as soon as it is hidden; + * you may not hide the panel and then re-show it later. + * Returns a disposable that you may use to hide and destroy the modal. + */ /** + * Given a function to dismiss the modal, return a React element for the content. + * Call the function when e.g. the user clicks a Cancel or Submit button. + */ /** Wrap options in an object so we can add new ones later without an explosion of params */ /** + * 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. + * + * + * @format + */ /* global Node */ /* global HTMLElement */function showModal(contentFactory, options = defaults) {const hostElement = document.createElement('div');const atomPanel = atom.workspace.addModalPanel({ item: hostElement, priority: options.priority, className: options.className });const shouldDismissOnClickOutsideModal = options.shouldDismissOnClickOutsideModal || (() => true);const shouldDismissOnPressEscape = options.shouldDismissOnPressEscape || (() => true);const element = atomPanel.getElement();const previouslyFocusedElement = document.activeElement;const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default(_rxjsBundlesRxMinJs.Observable.fromEvent(document, 'mousedown').subscribe(({ target }) => {if (!shouldDismissOnClickOutsideModal()) { + return; + }if (!( + target instanceof Node)) {throw new Error('Invariant violation: "target instanceof Node"');} + if ( + !atomPanel.getItem().contains(target) && + // don't count clicks on notifications or tooltips as clicks 'outside' + target.closest('atom-notifications, .tooltip') == null) + { + atomPanel.hide(); + } + }), + atomPanel.onDidChangeVisible(visible => { + if (!visible) { + disposable.dispose(); + } + }), + atom.commands.add('atom-workspace', 'core:cancel', () => { + if (shouldDismissOnPressEscape()) { + disposable.dispose(); + } + }), + () => { + // Call onDismiss before unmounting the component and destroying the panel: + if (options.onDismiss) { + options.onDismiss(); + } + _reactDom.default.unmountComponentAtNode(hostElement); + atomPanel.destroy(); + if ( + document.activeElement === document.body && + previouslyFocusedElement != null) + { + previouslyFocusedElement.focus(); + } + }); + + + _reactDom.default.render( + _react.createElement(ModalContainer, null, + contentFactory({ dismiss: disposable.dispose.bind(disposable), element })), + + hostElement, + () => { + if (options.onOpen) { + options.onOpen(); + } }); - const shouldDismissOnClickOutsideModal = - options.shouldDismissOnClickOutsideModal || (() => true); - const shouldDismissOnPressEscape = - options.shouldDismissOnPressEscape || (() => true); - - const element = atomPanel.getElement(); - const previouslyFocusedElement = document.activeElement; - const disposable = new UniversalDisposable( - Observable.fromEvent(document, 'mousedown').subscribe(({target}) => { - if (!shouldDismissOnClickOutsideModal()) { - return; - } - invariant(target instanceof Node); - if ( - !atomPanel.getItem().contains(target) && - // don't count clicks on notifications or tooltips as clicks 'outside' - target.closest('atom-notifications, .tooltip') == null - ) { - atomPanel.hide(); - } - }), - atomPanel.onDidChangeVisible(visible => { - if (!visible) { - disposable.dispose(); - } - }), - atom.commands.add('atom-workspace', 'core:cancel', () => { - if (shouldDismissOnPressEscape()) { - disposable.dispose(); - } - }), - () => { - // Call onDismiss before unmounting the component and destroying the panel: - if (options.onDismiss) { - options.onDismiss(); - } - ReactDOM.unmountComponentAtNode(hostElement); - atomPanel.destroy(); - if ( - document.activeElement === document.body && - previouslyFocusedElement != null - ) { - previouslyFocusedElement.focus(); - } - }, - ); - - ReactDOM.render( - - {contentFactory({dismiss: disposable.dispose.bind(disposable), element})} - , - hostElement, - () => { - if (options.onOpen) { - options.onOpen(); - } - }, - ); + return disposable; } /** Flow makes {} an unsealed object (eyeroll) */ -const defaults: Options = Object.freeze({}); +const defaults = Object.freeze({}); + + + -type Props = { - children?: any, -}; /** - * Just exists to provide a div that we can focus on mount. This ensures we steal focus from any - * editors or other panes while the modal is present. - */ -class ModalContainer extends React.Component { - render(): React.Node { + * Just exists to provide a div that we can focus on mount. This ensures we steal focus from any + * editors or other panes while the modal is present. + */ +class ModalContainer extends _react.Component { + render() { return ( -
      - - {this.props.children} - -
      - ); + _react.createElement('div', { tabIndex: '-1' }, + _react.createElement((_TabbableContainer || _load_TabbableContainer()).default, { contained: true }, + this.props.children))); + + + } - componentDidMount(): void { - const node = ReactDOM.findDOMNode(this); - invariant(node instanceof HTMLElement); + componentDidMount() { + const node = _reactDom.default.findDOMNode(this);if (!( + node instanceof HTMLElement)) {throw new Error('Invariant violation: "node instanceof HTMLElement"');} // Steal the focus away from any active editor or pane, setting it on the modal; // but don't steal focus away from a descendant. This can happen if a React element focuses // during its componentDidMount. For example, does this since the underlying @@ -162,5 +162,4 @@ class ModalContainer extends React.Component { if (!node.contains(document.activeElement)) { node.focus(); } - } -} + }} \ No newline at end of file diff --git a/modules/nuclide-commons-ui/spec/AtomInput-spec.js b/modules/nuclide-commons-ui/spec/AtomInput-spec.js index 741fc0c2..dd9ffca3 100644 --- a/modules/nuclide-commons-ui/spec/AtomInput-spec.js +++ b/modules/nuclide-commons-ui/spec/AtomInput-spec.js @@ -1,56 +1,56 @@ -/** - * 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 - * @format - */ - -import {sleep} from 'nuclide-commons/promise'; -import {AtomInput} from '../AtomInput'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; - -let reactElement: any; - -function createWithProps(props: any): any { - const hostEl = document.createElement('div'); - return ReactDOM.render(, hostEl); -} - -describe('AtomInput', () => { - afterEach(() => { +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _promise; + + + + + + + + + + + +function _load_promise() {return _promise = require('nuclide-commons/promise');}var _AtomInput; +function _load_AtomInput() {return _AtomInput = require('../AtomInput');} +var _react = _interopRequireWildcard(require('react')); +var _reactDom = _interopRequireDefault(require('react-dom'));function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */let reactElement;function createWithProps(props) {const hostEl = document.createElement('div');return _reactDom.default.render(_react.createElement((_AtomInput || _load_AtomInput()).AtomInput, props), hostEl);}describe('AtomInput', () => {afterEach(() => { if (reactElement) { - ReactDOM.unmountComponentAtNode( - // $FlowFixMe - ReactDOM.findDOMNode(reactElement).parentNode, - ); + _reactDom.default.unmountComponentAtNode( + // $FlowFixMe + _reactDom.default.findDOMNode(reactElement).parentNode); + } reactElement = null; }); it('honors the initialValue param', () => { - reactElement = createWithProps({initialValue: 'some text'}); + reactElement = createWithProps({ initialValue: 'some text' }); expect(reactElement.getText()).toBe('some text'); expect(reactElement.getTextEditor().getText()).toBe('some text'); }); it('focus() focuses the end of the line', () => { const initialValue = 'some text'; - reactElement = createWithProps({initialValue}); + reactElement = createWithProps({ initialValue }); expect(reactElement.getTextEditor().getCursorBufferPosition()).toEqual([ - 0, - 0, - ]); + 0, + 0]); + reactElement.focus(); expect(reactElement.getTextEditor().getCursorBufferPosition()).toEqual([ - 0, - initialValue.length, - ]); + 0, + initialValue.length]); + }); it('onDidChange() does not fire initially', () => { @@ -58,15 +58,15 @@ describe('AtomInput', () => { const onDidChange = jasmine.createSpy('onDidChange'); reactElement = createWithProps({ initialValue, - onDidChange, - }); + onDidChange }); + expect(onDidChange).not.toHaveBeenCalled(); }); it('onDidChange() is fired when the text changes', () => { const initialValue = 'some text'; - reactElement = createWithProps({initialValue}); + reactElement = createWithProps({ initialValue }); const onDidChange = jasmine.createSpy('onDidChange'); const disposable = reactElement.onDidChange(onDidChange); @@ -84,16 +84,16 @@ describe('AtomInput', () => { it('updates will stop firing when the component is unmounted', () => { const initialValue = 'some text'; const onDidChange = jasmine.createSpy('onDidChange'); - reactElement = createWithProps({initialValue, onDidChange}); + reactElement = createWithProps({ initialValue, onDidChange }); const textEditor = reactElement.getTextEditor(); textEditor.setText('the new text'); expect(onDidChange.calls.length).toBe(1); - ReactDOM.unmountComponentAtNode( - // $FlowFixMe - ReactDOM.findDOMNode(reactElement).parentNode, - ); + _reactDom.default.unmountComponentAtNode( + // $FlowFixMe + _reactDom.default.findDOMNode(reactElement).parentNode); + reactElement = null; textEditor.setText('even more new text'); @@ -101,17 +101,17 @@ describe('AtomInput', () => { }); it('does not leak TextEditorComponent', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { jasmine.useRealClock(); const hostEl = document.createElement('div'); - const component = ReactDOM.render(, hostEl); + const component = _reactDom.default.render(_react.createElement((_AtomInput || _load_AtomInput()).AtomInput, null), hostEl); const textEditor = component.getTextEditor(); const element = textEditor.getElement(); - ReactDOM.unmountComponentAtNode(hostEl); + _reactDom.default.unmountComponentAtNode(hostEl); // Cleanup occurs during the next tick. - await sleep(0); + yield (0, (_promise || _load_promise()).sleep)(0); expect(element.component).toBe(null); - }); + })); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons-ui/spec/AtomTextEditor-spec.js b/modules/nuclide-commons-ui/spec/AtomTextEditor-spec.js index b82b6639..377d3875 100644 --- a/modules/nuclide-commons-ui/spec/AtomTextEditor-spec.js +++ b/modules/nuclide-commons-ui/spec/AtomTextEditor-spec.js @@ -1,21 +1,21 @@ -/** - * 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 - * @format - */ - -import {sleep} from 'nuclide-commons/promise'; -import {AtomTextEditor} from '../AtomTextEditor'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import TestUtils from 'react-dom/test-utils'; -import invariant from 'assert'; +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _promise; + + + + + + + + + + + +function _load_promise() {return _promise = require('nuclide-commons/promise');}var _AtomTextEditor; +function _load_AtomTextEditor() {return _AtomTextEditor = require('../AtomTextEditor');} +var _react = _interopRequireWildcard(require('react')); +var _reactDom = _interopRequireDefault(require('react-dom'));var _testUtils; +function _load_testUtils() {return _testUtils = _interopRequireDefault(require('react-dom/test-utils'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + describe('nuclide-ui-atom-text-editor', () => { describe('when its `path` is set', () => { @@ -34,9 +34,9 @@ describe('nuclide-ui-atom-text-editor', () => { it('loads the desired `Grammar`', () => { // $FlowIgnore - const element: AtomTextEditor = TestUtils.renderIntoDocument( - , - ); + const element = (_testUtils || _load_testUtils()).default.renderIntoDocument( + _react.createElement((_AtomTextEditor || _load_AtomTextEditor()).AtomTextEditor, { path: '.test' })); + expect(element.getModel().getGrammar().scopeName).toEqual('text.test'); }); }); @@ -50,35 +50,35 @@ describe('nuclide-ui-atom-text-editor', () => { grammar2 = atom.grammars.loadGrammarSync('spec/grammars/test2.cson'); }); - afterEach(() => { - invariant(grammar1 != null); - atom.grammars.removeGrammarForScopeName(grammar1.scopeName); - invariant(grammar2 != null); + afterEach(() => {if (!( + grammar1 != null)) {throw new Error('Invariant violation: "grammar1 != null"');} + atom.grammars.removeGrammarForScopeName(grammar1.scopeName);if (!( + grammar2 != null)) {throw new Error('Invariant violation: "grammar2 != null"');} atom.grammars.removeGrammarForScopeName(grammar2.scopeName); }); it('updates the underlying models grammar', () => { // $FlowIgnore - const element: AtomTextEditor = TestUtils.renderIntoDocument( - , - ); + const element = (_testUtils || _load_testUtils()).default.renderIntoDocument( + _react.createElement((_AtomTextEditor || _load_AtomTextEditor()).AtomTextEditor, { path: '.test', grammar: grammar2 })); + expect(element.getModel().getGrammar().scopeName).toEqual('text.test2'); }); }); describe('when `readOnly`', () => { - let element: AtomTextEditor; + let element; describe('is true', () => { beforeEach(() => { // $FlowIgnore - element = TestUtils.renderIntoDocument( - , - ); + element = (_testUtils || _load_testUtils()).default.renderIntoDocument( + _react.createElement((_AtomTextEditor || _load_AtomTextEditor()).AtomTextEditor, { readOnly: true })); + }); - it('allows copying', () => { - invariant(element); + it('allows copying', () => {if (! + element) {throw new Error('Invariant violation: "element"');} const model = element.getModel(); model.setText('fraggle'); model.selectAll(); @@ -86,24 +86,24 @@ describe('nuclide-ui-atom-text-editor', () => { expect(atom.clipboard.read()).toEqual('fraggle'); }); - it('disallows inserting', () => { - invariant(element); + it('disallows inserting', () => {if (! + element) {throw new Error('Invariant violation: "element"');} const model = element.getModel(); model.setText('foobar'); model.insertNewline(); expect(model.getText()).toEqual('foobar'); }); - it('disallows pasting', () => { - invariant(element); + it('disallows pasting', () => {if (! + element) {throw new Error('Invariant violation: "element"');} const model = element.getModel(); atom.clipboard.write('foo bar baz'); model.pasteText(); expect(model.getText()).toEqual(''); }); - it('disallows deleting text', () => { - invariant(element); + it('disallows deleting text', () => {if (! + element) {throw new Error('Invariant violation: "element"');} const model = element.getModel(); model.setText('balloon'); model.selectAll(); @@ -111,8 +111,8 @@ describe('nuclide-ui-atom-text-editor', () => { expect(model.getText()).toEqual('balloon'); }); - it('disallows backspace', () => { - invariant(element); + it('disallows backspace', () => {if (! + element) {throw new Error('Invariant violation: "element"');} const model = element.getModel(); model.setText('foobar'); model.moveToEndOfLine(); @@ -124,11 +124,11 @@ describe('nuclide-ui-atom-text-editor', () => { describe('is undefined', () => { beforeEach(() => { // $FlowIgnore - element = TestUtils.renderIntoDocument(); + element = (_testUtils || _load_testUtils()).default.renderIntoDocument(_react.createElement((_AtomTextEditor || _load_AtomTextEditor()).AtomTextEditor, null)); }); - it('allows copying', () => { - invariant(element); + it('allows copying', () => {if (! + element) {throw new Error('Invariant violation: "element"');} const model = element.getModel(); model.setText('fraggle'); model.selectAll(); @@ -136,24 +136,24 @@ describe('nuclide-ui-atom-text-editor', () => { expect(atom.clipboard.read()).toEqual('fraggle'); }); - it('allows inserting', () => { - invariant(element); + it('allows inserting', () => {if (! + element) {throw new Error('Invariant violation: "element"');} const model = element.getModel(); model.setText('foobar'); model.insertNewline(); expect(model.getText()).toEqual('foobar\n'); }); - it('allows pasting', () => { - invariant(element); + it('allows pasting', () => {if (! + element) {throw new Error('Invariant violation: "element"');} const model = element.getModel(); atom.clipboard.write('foo bar baz'); model.pasteText(); expect(model.getText()).toEqual('foo bar baz'); }); - it('allows deleting text', () => { - invariant(element); + it('allows deleting text', () => {if (! + element) {throw new Error('Invariant violation: "element"');} const model = element.getModel(); model.setText('balloon'); model.selectAll(); @@ -161,8 +161,8 @@ describe('nuclide-ui-atom-text-editor', () => { expect(model.getText()).toEqual(''); }); - it('allows backspace', () => { - invariant(element); + it('allows backspace', () => {if (! + element) {throw new Error('Invariant violation: "element"');} const model = element.getModel(); model.setText('foobar'); model.moveToEndOfLine(); @@ -173,17 +173,27 @@ describe('nuclide-ui-atom-text-editor', () => { }); it('does not leak TextEditorComponent', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { jasmine.useRealClock(); const hostEl = document.createElement('div'); - const component = ReactDOM.render(, hostEl); + const component = _reactDom.default.render(_react.createElement((_AtomTextEditor || _load_AtomTextEditor()).AtomTextEditor, null), hostEl); const textEditor = component.getModel(); const element = textEditor.getElement(); - ReactDOM.unmountComponentAtNode(hostEl); + _reactDom.default.unmountComponentAtNode(hostEl); // Cleanup occurs during the next tick. - await sleep(0); + yield (0, (_promise || _load_promise()).sleep)(0); expect(element.component).toBe(null); - }); + })); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons-ui/spec/Checkbox-spec.js b/modules/nuclide-commons-ui/spec/Checkbox-spec.js index 8563b77a..22cf0cf2 100644 --- a/modules/nuclide-commons-ui/spec/Checkbox-spec.js +++ b/modules/nuclide-commons-ui/spec/Checkbox-spec.js @@ -1,34 +1,34 @@ -/** - * 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 - * @format - */ - -import {Checkbox} from '../Checkbox'; -import nullthrows from 'nullthrows'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import TestUtils from 'react-dom/test-utils'; - -let hostEl; - -function createWithProps(props) { - return ReactDOM.render(, nullthrows(hostEl)); -} - -describe('Checkbox', () => { - beforeEach(() => { - hostEl = document.createElement('div'); - }); +'use strict';var _Checkbox; + + + + + + + + + + +function _load_Checkbox() {return _Checkbox = require('../Checkbox');}var _nullthrows; +function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));} +var _react = _interopRequireWildcard(require('react')); +var _reactDom = _interopRequireDefault(require('react-dom'));var _testUtils; +function _load_testUtils() {return _testUtils = _interopRequireDefault(require('react-dom/test-utils'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +let hostEl; /** + * 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. + * + * + * @format + */function createWithProps(props) {return _reactDom.default.render(_react.createElement((_Checkbox || _load_Checkbox()).Checkbox, props), (0, (_nullthrows || _load_nullthrows()).default)(hostEl));}describe('Checkbox', () => {beforeEach(() => {hostEl = document.createElement('div');}); afterEach(() => { - ReactDOM.unmountComponentAtNode(hostEl); + _reactDom.default.unmountComponentAtNode(hostEl); hostEl = null; }); @@ -37,14 +37,14 @@ describe('Checkbox', () => { const reactElement = createWithProps({ checked: false, label: 'click me!', - onChange, - }); + onChange }); + + + const inputEl = (0, (_nullthrows || _load_nullthrows()).default)( + (_testUtils || _load_testUtils()).default.findRenderedDOMComponentWithTag(reactElement, 'input')); - const inputEl = nullthrows( - TestUtils.findRenderedDOMComponentWithTag(reactElement, 'input'), - ); // Unfortunately, TestUtils does not seem to turn a click into a change event for a checkbox. - TestUtils.Simulate.change(inputEl); + (_testUtils || _load_testUtils()).default.Simulate.change(inputEl); expect(onChange.callCount).toBe(1); // Nor does it seem to change the state of the checkbox, as the following fails: @@ -57,13 +57,13 @@ describe('Checkbox', () => { checked: false, indeterminate: true, label: 'click me!', - onChange() {}, - }); + onChange() {} }); + + + const inputEl = (0, (_nullthrows || _load_nullthrows()).default)( + (_testUtils || _load_testUtils()).default.findRenderedDOMComponentWithTag(reactElement, 'input')); - const inputEl = nullthrows( - TestUtils.findRenderedDOMComponentWithTag(reactElement, 'input'), - ); // $FlowFixMe(>=0.66.0) Flow suppress expect(inputEl.indeterminate).toBe(true); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons-ui/spec/ClickOutsideBoundry-spec.js b/modules/nuclide-commons-ui/spec/ClickOutsideBoundry-spec.js index 65bcbb54..c1d0b42a 100644 --- a/modules/nuclide-commons-ui/spec/ClickOutsideBoundry-spec.js +++ b/modules/nuclide-commons-ui/spec/ClickOutsideBoundry-spec.js @@ -1,3 +1,28 @@ +'use strict'; + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react')); + +var _reactDom = require('react-dom');var _ClickOutsideBoundary; +function _load_ClickOutsideBoundary() {return _ClickOutsideBoundary = _interopRequireDefault(require('../ClickOutsideBoundary'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} + +const clickId = id => { + const node = document.getElementById(id);if (!( + node != null)) {throw new Error(`node ${id} should be present in the DOM`);} + node.click(); +}; + +// A component which removes itself from the DOM when clicked. +// $FlowFixMe(>=0.53.0) Flow suppress /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,41 +31,16 @@ * 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 + * * @format - */ + */class ClickAway extends _react.Component {constructor(props) {super(props);this.handleClick = () => {this.setState({ visible: false });};this.state = { visible: true };}render() { + return this.state.visible ? + _react.createElement('span', Object.assign({}, this.props, { onClick: this.handleClick }), 'Click to dismiss') : -import * as React from 'react'; -import invariant from 'assert'; -import {render} from 'react-dom'; -import ClickOutsideBoundary from '../ClickOutsideBoundary'; -const clickId = (id: string) => { - const node = document.getElementById(id); - invariant(node != null, `node ${id} should be present in the DOM`); - node.click(); -}; + null; + }} -// A component which removes itself from the DOM when clicked. -// $FlowFixMe(>=0.53.0) Flow suppress -class ClickAway extends React.Component<$FlowFixMeProps, $FlowFixMeState> { - constructor(props) { - super(props); - this.state = {visible: true}; - } - - handleClick = () => { - this.setState({visible: false}); - }; - - render() { - return this.state.visible ? ( - - Click to dismiss - - ) : null; - } -} describe('ClickOutsideBoundary - onClickOutside handler', () => { let app; @@ -58,28 +58,28 @@ describe('ClickOutsideBoundary - onClickOutside handler', () => { describe('_is_ called for an external click', () => { it('on a parent', () => { - render( -
      - -
      - -
      , - app, - ); + (0, _reactDom.render)( + _react.createElement('div', { id: 'container' }, + _react.createElement((_ClickOutsideBoundary || _load_ClickOutsideBoundary()).default, { onClickOutside: onClickOutside }, + _react.createElement('div', { id: 'target' }))), + + + app); + clickId('container'); expect(onClickOutside).toHaveBeenCalled(); }); it('on a sibling', () => { - render( -
      - -
      - -
      -
      , - app, - ); + (0, _reactDom.render)( + _react.createElement('div', null, + _react.createElement((_ClickOutsideBoundary || _load_ClickOutsideBoundary()).default, { onClickOutside: onClickOutside }, + _react.createElement('div', { id: 'target' })), + + _react.createElement('div', { id: 'sibling' })), + + app); + clickId('sibling'); expect(onClickOutside).toHaveBeenCalled(); }); @@ -87,15 +87,15 @@ describe('ClickOutsideBoundary - onClickOutside handler', () => { it('on a sibling that disappears after render', () => { // This would fail if we tool the approach of ignoring all // clicks on elements that were not in the DOM. - render( -
      - -
      - - -
      , - app, - ); + (0, _reactDom.render)( + _react.createElement('div', null, + _react.createElement((_ClickOutsideBoundary || _load_ClickOutsideBoundary()).default, { onClickOutside: onClickOutside }, + _react.createElement('div', { id: 'target' })), + + _react.createElement(ClickAway, { id: 'click-away' })), + + app); + clickId('click-away'); expect(onClickOutside).toHaveBeenCalled(); }); @@ -103,12 +103,12 @@ describe('ClickOutsideBoundary - onClickOutside handler', () => { describe('is _not_ called for an internal click', () => { it('under normal conditions', () => { - render( - -
      - , - app, - ); + (0, _reactDom.render)( + _react.createElement((_ClickOutsideBoundary || _load_ClickOutsideBoundary()).default, { onClickOutside: onClickOutside }, + _react.createElement('div', { id: 'target' })), + + app); + clickId('target'); expect(onClickOutside).not.toHaveBeenCalled(); }); @@ -116,17 +116,17 @@ describe('ClickOutsideBoundary - onClickOutside handler', () => { it('when the target leaves the DOM before the event reaches window.document', () => { // A simple approach: `this.rootNode.contains(e.target)` would fail this test. const onClickInside = jasmine.createSpy('onClickInside'); - render( - -
      - -
      -
      , - app, - ); + (0, _reactDom.render)( + _react.createElement((_ClickOutsideBoundary || _load_ClickOutsideBoundary()).default, { onClickOutside: onClickOutside }, + _react.createElement('div', { onClick: onClickInside }, + _react.createElement(ClickAway, { id: 'click-away' }))), + + + app); + clickId('click-away'); expect(onClickInside).toHaveBeenCalled(); expect(onClickOutside).not.toHaveBeenCalled(); }); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons-ui/spec/Dropdown-spec.js b/modules/nuclide-commons-ui/spec/Dropdown-spec.js index a9e2f018..ead04a61 100644 --- a/modules/nuclide-commons-ui/spec/Dropdown-spec.js +++ b/modules/nuclide-commons-ui/spec/Dropdown-spec.js @@ -1,34 +1,34 @@ -/** - * 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 - * @format - */ - -import {Dropdown} from '../Dropdown'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import TestUtils from 'react-dom/test-utils'; - -const {renderIntoDocument, scryRenderedDOMComponentsWithTag} = TestUtils; - -describe('Dropdown', () => { - it('honors the value param', () => { - const component = renderIntoDocument( - {}} - value={'vbar'} - />, - ); +'use strict';var _Dropdown; + + + + + + + + + + + +function _load_Dropdown() {return _Dropdown = require('../Dropdown');} +var _react = _interopRequireWildcard(require('react')); +var _reactDom = _interopRequireDefault(require('react-dom'));var _testUtils; +function _load_testUtils() {return _testUtils = _interopRequireDefault(require('react-dom/test-utils'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} /** + * 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. + * + * + * @format + */const { renderIntoDocument, scryRenderedDOMComponentsWithTag } = (_testUtils || _load_testUtils()).default;describe('Dropdown', () => {it('honors the value param', () => {const component = renderIntoDocument(_react.createElement((_Dropdown || _load_Dropdown()).Dropdown, { options: [{ label: 'foo', value: 'vfoo' }, { label: 'bar', value: 'vbar' }], onChange: newValue => {}, value: 'vbar' })); + + const button = scryRenderedDOMComponentsWithTag(component, 'button'); // $FlowFixMe - expect(ReactDOM.findDOMNode(button[0]).innerText).toBe('bar'); + expect(_reactDom.default.findDOMNode(button[0]).innerText).toBe('bar'); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons-ui/spec/HighlightedCode-spec.js b/modules/nuclide-commons-ui/spec/HighlightedCode-spec.js index 877b0210..b5be870a 100644 --- a/modules/nuclide-commons-ui/spec/HighlightedCode-spec.js +++ b/modules/nuclide-commons-ui/spec/HighlightedCode-spec.js @@ -1,82 +1,82 @@ -/** - * 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 - * @format - */ - -import dedent from 'dedent'; -import nullthrows from 'nullthrows'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import { - highlightCode, - highlightCodeHtml, - HighlightedCode, -} from '../HighlightedCode'; +'use strict';var _dedent; + + + + + + + + + + + +function _load_dedent() {return _dedent = _interopRequireDefault(require('dedent'));}var _nullthrows; +function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));} +var _react = _interopRequireWildcard(require('react')); +var _reactDom = _interopRequireDefault(require('react-dom'));var _HighlightedCode; +function _load_HighlightedCode() {return _HighlightedCode = require('../HighlightedCode');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + + + + describe('highlightCode', () => { - let grammar: atom$Grammar; + let grammar; beforeEach(() => { waitsForPromise(() => atom.packages.activatePackage('language-gfm')); runs(() => { - grammar = nullthrows(atom.grammars.grammarForScopeName('source.gfm')); + grammar = (0, (_nullthrows || _load_nullthrows()).default)(atom.grammars.grammarForScopeName('source.gfm')); }); }); it('is able to tokenize lines using a grammar', () => { - const tokens = highlightCode( - grammar, - dedent` + const tokens = (0, (_HighlightedCode || _load_HighlightedCode()).highlightCode)( + grammar, + (_dedent || _load_dedent()).default` #Heading __bold__ *italic* - `, - ); + `); + // Desperately needs Jest snapshots! expect(tokens).toEqual([ - [ - {type: 'start', className: 'syntax--source syntax--gfm'}, - { - type: 'start', - className: - 'syntax--markup syntax--heading syntax--heading-1 syntax--gfm', - }, - { - type: 'start', - className: - 'syntax--markup syntax--heading syntax--marker syntax--gfm', - }, - {type: 'value', value: '#'}, - {type: 'end'}, - {type: 'value', value: 'Heading'}, - {type: 'end'}, - {type: 'end'}, - ], - [ - {type: 'start', className: 'syntax--source syntax--gfm'}, - {type: 'start', className: 'syntax--markup syntax--bold syntax--gfm'}, - {type: 'value', value: '__'}, - {type: 'value', value: 'bold'}, - {type: 'value', value: '__'}, - {type: 'end'}, - {type: 'end'}, - ], - [ - {type: 'start', className: 'syntax--source syntax--gfm'}, - {type: 'start', className: 'syntax--markup syntax--italic syntax--gfm'}, - {type: 'value', value: '*'}, - {type: 'value', value: 'italic'}, - {type: 'value', value: '*'}, - {type: 'end'}, - {type: 'end'}, - ], - ]); + [ + { type: 'start', className: 'syntax--source syntax--gfm' }, + { + type: 'start', + className: + 'syntax--markup syntax--heading syntax--heading-1 syntax--gfm' }, + + { + type: 'start', + className: + 'syntax--markup syntax--heading syntax--marker syntax--gfm' }, + + { type: 'value', value: '#' }, + { type: 'end' }, + { type: 'value', value: 'Heading' }, + { type: 'end' }, + { type: 'end' }], + + [ + { type: 'start', className: 'syntax--source syntax--gfm' }, + { type: 'start', className: 'syntax--markup syntax--bold syntax--gfm' }, + { type: 'value', value: '__' }, + { type: 'value', value: 'bold' }, + { type: 'value', value: '__' }, + { type: 'end' }, + { type: 'end' }], + + [ + { type: 'start', className: 'syntax--source syntax--gfm' }, + { type: 'start', className: 'syntax--markup syntax--italic syntax--gfm' }, + { type: 'value', value: '*' }, + { type: 'value', value: 'italic' }, + { type: 'value', value: '*' }, + { type: 'end' }, + { type: 'end' }]]); + + }); it('becomes HTML using highlightCodeHtml', () => { @@ -91,14 +91,14 @@ describe('highlightCode', () => { `.replace(/\s+/g, ''); - const html = highlightCodeHtml(grammar, '#Heading'); + const html = (0, (_HighlightedCode || _load_HighlightedCode()).highlightCodeHtml)(grammar, '#Heading'); expect(html.replace(/\s+/g, '')).toBe(EXPECTED); const node = document.createElement('div'); - ReactDOM.render( - , - node, - ); + _reactDom.default.render( + _react.createElement((_HighlightedCode || _load_HighlightedCode()).HighlightedCode, { grammar: grammar, code: '#Heading' }), + node); + expect(node.innerHTML.replace(/\s+/g, '')).toContain(EXPECTED); }); @@ -110,7 +110,17 @@ describe('highlightCode', () => { `.replace(/\s+/g, ''); - const html = highlightCodeHtml(grammar, '<>'); + const html = (0, (_HighlightedCode || _load_HighlightedCode()).highlightCodeHtml)(grammar, '<>'); expect(html.replace(/\s+/g, '')).toBe(EXPECTED); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons-ui/spec/NuclideRadioGroup-spec.js b/modules/nuclide-commons-ui/spec/NuclideRadioGroup-spec.js index d04bf3f8..cabad092 100644 --- a/modules/nuclide-commons-ui/spec/NuclideRadioGroup-spec.js +++ b/modules/nuclide-commons-ui/spec/NuclideRadioGroup-spec.js @@ -1,67 +1,67 @@ -/** - * 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 - * @format - */ - -/* global Element */ - -import invariant from 'assert'; -import RadioGroup from '../RadioGroup'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import TestUtils from 'react-dom/test-utils'; +'use strict';var _RadioGroup; + + + + + + + + + + + + + + +function _load_RadioGroup() {return _RadioGroup = _interopRequireDefault(require('../RadioGroup'));} +var _react = _interopRequireWildcard(require('react')); +var _reactDom = _interopRequireDefault(require('react-dom'));var _testUtils; +function _load_testUtils() {return _testUtils = _interopRequireDefault(require('react-dom/test-utils'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} const { Simulate, renderIntoDocument, - scryRenderedDOMComponentsWithTag, -} = TestUtils; - -describe('RadioGroup', () => { - it('honors the selectedIndex param', () => { - const component = renderIntoDocument( - , - ); - expect(component.props.selectedIndex).toBe(1); - - const radioInputs = scryRenderedDOMComponentsWithTag(component, 'input'); + scryRenderedDOMComponentsWithTag } = (_testUtils || _load_testUtils()).default; /** + * 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. + * + * + * @format + */ /* global Element */describe('RadioGroup', () => {it('honors the selectedIndex param', () => {const component = renderIntoDocument(_react.createElement((_RadioGroup || _load_RadioGroup()).default, { optionLabels: ['foo', 'bar'], selectedIndex: 1 }));expect(component.props.selectedIndex).toBe(1);const radioInputs = scryRenderedDOMComponentsWithTag(component, 'input'); // $FlowFixMe - expect(ReactDOM.findDOMNode(radioInputs[0]).checked).toBe(false); + expect(_reactDom.default.findDOMNode(radioInputs[0]).checked).toBe(false); // $FlowFixMe - expect(ReactDOM.findDOMNode(radioInputs[1]).checked).toBe(true); + expect(_reactDom.default.findDOMNode(radioInputs[1]).checked).toBe(true); }); it('should use the correct, unique radio group name', () => { - const props = {optionLabels: ['foo', 'bar'], selectedIndex: 1}; - const component = renderIntoDocument(); + const props = { optionLabels: ['foo', 'bar'], selectedIndex: 1 }; + const component = renderIntoDocument(_react.createElement((_RadioGroup || _load_RadioGroup()).default, props)); const radioInputs = scryRenderedDOMComponentsWithTag(component, 'input'); // Global uid is `1` as this point, since this is the second RadioGroup component to be created. // $FlowFixMe - expect(ReactDOM.findDOMNode(radioInputs[0]).getAttribute('name')).toEqual( - 'radiogroup-1', - ); + expect(_reactDom.default.findDOMNode(radioInputs[0]).getAttribute('name')).toEqual( + 'radiogroup-1'); + // $FlowFixMe - expect(ReactDOM.findDOMNode(radioInputs[1]).getAttribute('name')).toEqual( - 'radiogroup-1', - ); - const component2 = renderIntoDocument(); + expect(_reactDom.default.findDOMNode(radioInputs[1]).getAttribute('name')).toEqual( + 'radiogroup-1'); + + const component2 = renderIntoDocument(_react.createElement((_RadioGroup || _load_RadioGroup()).default, props)); const radioInputs2 = scryRenderedDOMComponentsWithTag(component2, 'input'); // $FlowFixMe - expect(ReactDOM.findDOMNode(radioInputs2[0]).getAttribute('name')).toEqual( - 'radiogroup-2', - ); + expect(_reactDom.default.findDOMNode(radioInputs2[0]).getAttribute('name')).toEqual( + 'radiogroup-2'); + // $FlowFixMe - expect(ReactDOM.findDOMNode(radioInputs2[1]).getAttribute('name')).toEqual( - 'radiogroup-2', - ); + expect(_reactDom.default.findDOMNode(radioInputs2[1]).getAttribute('name')).toEqual( + 'radiogroup-2'); + }); it('calls its onSelectedChange handler when a radio input is changed', () => { @@ -70,16 +70,16 @@ describe('RadioGroup', () => { const props = { optionLabels: ['foo', 'bar'], selectedIndex: 0, - onSelectedChange, - }; - const component = renderIntoDocument(); + onSelectedChange }; + + const component = renderIntoDocument(_react.createElement((_RadioGroup || _load_RadioGroup()).default, props)); const radioInputs = scryRenderedDOMComponentsWithTag(component, 'input'); - const secondRadioElement = radioInputs[1]; - invariant(secondRadioElement instanceof Element); + const secondRadioElement = radioInputs[1];if (!( + secondRadioElement instanceof Element)) {throw new Error('Invariant violation: "secondRadioElement instanceof Element"');} - const foundRadio = ReactDOM.findDOMNode(secondRadioElement); - invariant(foundRadio instanceof Element); + const foundRadio = _reactDom.default.findDOMNode(secondRadioElement);if (!( + foundRadio instanceof Element)) {throw new Error('Invariant violation: "foundRadio instanceof Element"');} Simulate.change(foundRadio); expect(onSelectedChange.mostRecentCall.args[0]).toEqual(1); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons-ui/spec/ReactMountRootElement-spec.js b/modules/nuclide-commons-ui/spec/ReactMountRootElement-spec.js index 028c9b94..bbea29f0 100644 --- a/modules/nuclide-commons-ui/spec/ReactMountRootElement-spec.js +++ b/modules/nuclide-commons-ui/spec/ReactMountRootElement-spec.js @@ -1,14 +1,14 @@ -/** - * 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 - * @format - */ +'use strict'; /** + * 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. + * + * + * @format + */ const modulePath = require.resolve('../ReactMountRootElement'); @@ -22,4 +22,4 @@ describe('ReactMountRootElement', () => { const createdElement = new element2(); expect(createdElement.constructor.name).toBe('nuclide-react-mount-root'); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons-ui/spec/Table-spec.js b/modules/nuclide-commons-ui/spec/Table-spec.js index 5502f8c2..8f1c94b1 100644 --- a/modules/nuclide-commons-ui/spec/Table-spec.js +++ b/modules/nuclide-commons-ui/spec/Table-spec.js @@ -1,30 +1,30 @@ -/** - * 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 - * @format - */ +'use strict';var _Table; + + + + + + + + + + + +function _load_Table() {return _Table = require('../Table');} + + -import { - _calculateColumnWidths, - _calculatePreferredColumnWidths, -} from '../Table'; describe('Table', () => { it('correctly distributes widths according to percentage, regardless of min width', () => { - const calculated = _calculateColumnWidths({ - preferredWidths: {a: 0.5, b: 0.5}, - minWidths: {a: 25, b: 50}, + const calculated = (0, (_Table || _load_Table())._calculateColumnWidths)({ + preferredWidths: { a: 0.5, b: 0.5 }, + minWidths: { a: 25, b: 50 }, tableWidth: 100, columnOrder: ['a', 'b'], - resizeOffset: null, - }); - expectClose(calculated, {a: 0.5, b: 0.5}); + resizeOffset: null }); + + expectClose(calculated, { a: 0.5, b: 0.5 }); }); it("doesn't change the column widths when a resize is ended", () => { @@ -33,70 +33,75 @@ describe('Table', () => { // all of the column widths MUST be continuous; in other words, the widths calculated from your // new distribution preferences must match the width calculated from your old distribution // preferences at that drag offset. - const minWidths = {a: 25, b: 50}; + const minWidths = { a: 25, b: 50 }; const tableWidth = 100; const columnOrder = ['a', 'b']; - const duringDrag = _calculateColumnWidths({ - preferredWidths: {a: 0.5, b: 0.5}, - resizeOffset: {resizerLocation: 0, deltaPx: -10}, + const duringDrag = (0, (_Table || _load_Table())._calculateColumnWidths)({ + preferredWidths: { a: 0.5, b: 0.5 }, + resizeOffset: { resizerLocation: 0, deltaPx: -10 }, minWidths, tableWidth, - columnOrder, - }); - expect(duringDrag).toEqual({a: 0.4, b: 0.6}); - const afterDrag = _calculateColumnWidths({ - preferredWidths: _calculatePreferredColumnWidths({ + columnOrder }); + + expect(duringDrag).toEqual({ a: 0.4, b: 0.6 }); + const afterDrag = (0, (_Table || _load_Table())._calculateColumnWidths)({ + preferredWidths: (0, (_Table || _load_Table())._calculatePreferredColumnWidths)({ currentWidths: duringDrag, minWidths, - tableWidth, - }), + tableWidth }), + resizeOffset: null, minWidths, tableWidth, - columnOrder, - }); + columnOrder }); + expectClose(afterDrag, duringDrag); }); it("doesn't allow resizing below a column's min width", () => { - const calculated = _calculateColumnWidths({ - preferredWidths: {a: 0.5, b: 0.5}, - minWidths: {a: 25, b: 50}, + const calculated = (0, (_Table || _load_Table())._calculateColumnWidths)({ + preferredWidths: { a: 0.5, b: 0.5 }, + minWidths: { a: 25, b: 50 }, tableWidth: 100, columnOrder: ['a', 'b'], - resizeOffset: {resizerLocation: 0, deltaPx: -50}, - }); - expectClose(calculated, {a: 0.25, b: 0.75}); + resizeOffset: { resizerLocation: 0, deltaPx: -50 } }); + + expectClose(calculated, { a: 0.25, b: 0.75 }); }); it('recognizes when a column is at its min width when calculating preferred distributions', () => { - const preferredWidths = _calculatePreferredColumnWidths({ - currentWidths: {a: 0.2, b: 0.2, c: 0.6}, - minWidths: {a: 25, b: 0, c: 0}, - tableWidth: 100, - }); + const preferredWidths = (0, (_Table || _load_Table())._calculatePreferredColumnWidths)({ + currentWidths: { a: 0.2, b: 0.2, c: 0.6 }, + minWidths: { a: 25, b: 0, c: 0 }, + tableWidth: 100 }); + // The user prefers "a" to be at its min width, i.e. have a 0 distribution, and the other // columns to have a 1:3 ratio. - expectClose(preferredWidths, {a: 0, b: 0.25, c: 0.75}); + expectClose(preferredWidths, { a: 0, b: 0.25, c: 0.75 }); }); it('shrinks multiple columns to their minimum if it has to in order to accomodate your resize', () => { - const calculated = _calculateColumnWidths({ - preferredWidths: {a: 0.25, b: 0.25, c: 0.25, d: 0.25}, - minWidths: {a: 10, b: 10, c: 10, d: 10}, + const calculated = (0, (_Table || _load_Table())._calculateColumnWidths)({ + preferredWidths: { a: 0.25, b: 0.25, c: 0.25, d: 0.25 }, + minWidths: { a: 10, b: 10, c: 10, d: 10 }, tableWidth: 100, columnOrder: ['a', 'b', 'c', 'd'], - resizeOffset: {resizerLocation: 0, deltaPx: 35}, - }); - expectClose(calculated, {a: 0.6, b: 0.1, c: 0.1, d: 0.2}); + resizeOffset: { resizerLocation: 0, deltaPx: 35 } }); + + expectClose(calculated, { a: 0.6, b: 0.1, c: 0.1, d: 0.2 }); }); }); // Because we're dealing with percentages represented as floating point numbers, a little bit of // deviation is expected. (`1 - 0.1 - 0.1 - 0.1 !== 0.7`) -const expectClose = (a, b) => { - expect(Object.keys(a).length).toBe(Object.keys(b).length); - Object.keys(a).forEach(k => { - expect(a[k]).toBeCloseTo(b[k], 10); - }); -}; +/** + * 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. + * + * + * @format + */const expectClose = (a, b) => {expect(Object.keys(a).length).toBe(Object.keys(b).length);Object.keys(a).forEach(k => {expect(a[k]).toBeCloseTo(b[k], 10);});}; \ No newline at end of file diff --git a/modules/nuclide-commons-ui/spec/Tabs-spec.js b/modules/nuclide-commons-ui/spec/Tabs-spec.js index 72b6b2f2..0286bd36 100644 --- a/modules/nuclide-commons-ui/spec/Tabs-spec.js +++ b/modules/nuclide-commons-ui/spec/Tabs-spec.js @@ -1,41 +1,41 @@ -/** - * 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 - * @format - */ - -import Tabs from '../Tabs'; -import * as React from 'react'; -import ReactDOM from 'react-dom'; -import TestUtils from 'react-dom/test-utils'; - -const { - Simulate, - // $FlowFixMe(>=0.66.0) Flow suppress - SimulateNative, - renderIntoDocument, - scryRenderedDOMComponentsWithClass, -} = TestUtils; - -describe('Checkbox', () => { - it('notifies callback of tab changes', () => { +'use strict';var _Tabs; + + + + + + + + + + + +function _load_Tabs() {return _Tabs = _interopRequireDefault(require('../Tabs'));} +var _react = _interopRequireWildcard(require('react')); +var _reactDom = _interopRequireDefault(require('react-dom'));var _testUtils; +function _load_testUtils() {return _testUtils = _interopRequireDefault(require('react-dom/test-utils'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */const { Simulate, // $FlowFixMe(>=0.66.0) Flow suppress + SimulateNative, renderIntoDocument, scryRenderedDOMComponentsWithClass } = (_testUtils || _load_testUtils()).default;describe('Checkbox', () => {it('notifies callback of tab changes', () => { const onChange = jasmine.createSpy('onChange'); const props = { tabs: [ - {name: 'first', tabContent: 123}, - {name: 'second', tabContent: 456}, - ], + { name: 'first', tabContent: _react.createElement('i', null, '123') }, + { name: 'second', tabContent: _react.createElement('i', null, '456') }], + activeTabName: 'first', - onActiveTabChange: onChange, - }; - const component = renderIntoDocument(); + onActiveTabChange: onChange }; + + const component = renderIntoDocument(_react.createElement((_Tabs || _load_Tabs()).default, props)); const node = scryRenderedDOMComponentsWithClass(component, 'title')[1]; Simulate.click(node); @@ -48,19 +48,19 @@ describe('Checkbox', () => { const props = { tabs: [ - {name: 'first', tabContent: 123}, - {name: 'second', tabContent: 456}, - ], + { name: 'first', tabContent: _react.createElement('i', null, '123') }, + { name: 'second', tabContent: _react.createElement('i', null, '456') }], + activeTabName: 'first', triggeringEvent: 'onMouseEnter', - onActiveTabChange: onChange, - }; - const component = renderIntoDocument(); + onActiveTabChange: onChange }; + + const component = renderIntoDocument(_react.createElement((_Tabs || _load_Tabs()).default, props)); const node = scryRenderedDOMComponentsWithClass(component, 'title')[1]; // `Simulate` does not currently support mouseEnter: https://github.com/facebook/react/issues/1297. - SimulateNative.mouseOver(ReactDOM.findDOMNode(node)); + SimulateNative.mouseOver(_reactDom.default.findDOMNode(node)); expect(onChange).toHaveBeenCalledWith(props.tabs[1]); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons-ui/spec/highlightText-spec.js b/modules/nuclide-commons-ui/spec/highlightText-spec.js index d3ea886a..dbd2d4d5 100644 --- a/modules/nuclide-commons-ui/spec/highlightText-spec.js +++ b/modules/nuclide-commons-ui/spec/highlightText-spec.js @@ -1,50 +1,60 @@ -/** - * 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 - * @format - */ - -import highlightText from '../highlightText'; +'use strict';var _highlightText; + + + + + + + + + + + +function _load_highlightText() {return _highlightText = _interopRequireDefault(require('../highlightText'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} describe('highlightText', () => { it('returns no ranges for no interpolated text', () => { - expect(highlightText`foo bar baz`).toEqual({ + expect((_highlightText || _load_highlightText()).default`foo bar baz`).toEqual({ text: 'foo bar baz', - matchRanges: [], - }); + matchRanges: [] }); + }); it('returns ranges to highlight interpolated values', () => { - expect(highlightText`foo ${1 + 2} bar ${'baz'} baz`).toEqual({ + expect((_highlightText || _load_highlightText()).default`foo ${1 + 2} bar ${'baz'} baz`).toEqual({ text: 'foo 3 bar baz baz', - matchRanges: [[4, 5], [10, 13]], - }); + matchRanges: [[4, 5], [10, 13]] }); + }); it("highlights the entire string if it's entirely interpolated", () => { - expect(highlightText`${'hello'}`).toEqual({ + expect((_highlightText || _load_highlightText()).default`${'hello'}`).toEqual({ text: 'hello', - matchRanges: [[0, 5]], - }); + matchRanges: [[0, 5]] }); + }); it('works with an interpolated value at the beginning', () => { - expect(highlightText`${1 + 2} bar ${'baz'} baz`).toEqual({ + expect((_highlightText || _load_highlightText()).default`${1 + 2} bar ${'baz'} baz`).toEqual({ text: '3 bar baz baz', - matchRanges: [[0, 1], [6, 9]], - }); + matchRanges: [[0, 1], [6, 9]] }); + }); it('works with an interpolated value at the end', () => { - expect(highlightText`foo ${1 + 2} bar ${'baz'}`).toEqual({ + expect((_highlightText || _load_highlightText()).default`foo ${1 + 2} bar ${'baz'}`).toEqual({ text: 'foo 3 bar baz', - matchRanges: [[4, 5], [10, 13]], - }); + matchRanges: [[4, 5], [10, 13]] }); + }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons-ui/spec/observable-dom-spec.js b/modules/nuclide-commons-ui/spec/observable-dom-spec.js index 7a08035b..4ee99076 100644 --- a/modules/nuclide-commons-ui/spec/observable-dom-spec.js +++ b/modules/nuclide-commons-ui/spec/observable-dom-spec.js @@ -1,72 +1,72 @@ -/** - * 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 - * @format - */ - -import invariant from 'assert'; -import {Observable} from 'rxjs'; - -import {_DOMObserverObservable as DOMObserverObservable} from '../observable-dom'; - -describe('new DOMObserverObservable', () => { - let observerInstance; - - beforeEach(() => { - observerInstance = null; - }); +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + + + + + + + + + + + + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _observableDom; + +function _load_observableDom() {return _observableDom = require('../observable-dom');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */describe('new DOMObserverObservable', () => {let observerInstance;beforeEach(() => {observerInstance = null;});class MockDOMObserver { + - class MockDOMObserver { - _args: Array; - _callback: Function; - _connected: boolean; constructor(callback) { this._callback = callback; observerInstance = this; } - observe(...args: any[]) { + observe(...args) { this._args = args; this._connected = true; } disconnect() { this._connected = false; - } - } + }} + it('does not construct a DOM Observer until the Rx Observable is subscribed to', () => { // $FlowFixMe(>=0.55.0) Flow suppress - const o = new DOMObserverObservable(MockDOMObserver, 'some', 'additional', { - args: true, - }); + const o = new (_observableDom || _load_observableDom())._DOMObserverObservable(MockDOMObserver, 'some', 'additional', { + args: true }); + expect(observerInstance).toBe(null); - const subscription = o.subscribe(() => {}); - invariant(observerInstance != null); + const subscription = o.subscribe(() => {});if (!( + observerInstance != null)) {throw new Error('Invariant violation: "observerInstance != null"');} expect(observerInstance._args).toEqual([ - 'some', - 'additional', - {args: true}, - ]); + 'some', + 'additional', + { args: true }]); + expect(observerInstance._connected).toBe(true); subscription.unsubscribe(); }); it('calls disconnect on the underlying DOM Observer when unsubscribe is called', () => { - const o = new DOMObserverObservable(MockDOMObserver, 'some', 'additional', { - args: true, - }); - const subscription = o.subscribe(() => {}); + const o = new (_observableDom || _load_observableDom())._DOMObserverObservable(MockDOMObserver, 'some', 'additional', { + args: true }); - invariant(observerInstance != null); + const subscription = o.subscribe(() => {});if (!( + + observerInstance != null)) {throw new Error('Invariant violation: "observerInstance != null"');} expect(observerInstance._connected).toBe(true); subscription.unsubscribe(); @@ -74,46 +74,46 @@ describe('new DOMObserverObservable', () => { }); it( - 'by default (without a call to .flattenEntries()) creates an observable of ' + - 'the elements emitted from the DOM Observer', - () => { - class MockDOMObserverEmitsArray extends MockDOMObserver { - observe(...args: Array) { - super.observe(...args); - Observable.interval(1) - .mapTo(['foo', 'bar', 'baz']) - .take(2) - .subscribe(this._callback); - } - } - - waitsForPromise(async () => { - const output = await new DOMObserverObservable( - MockDOMObserverEmitsArray, - 'arg', - ) - .take(2) - .toArray() - .toPromise(); - expect(output).toEqual([['foo', 'bar', 'baz'], ['foo', 'bar', 'baz']]); - }); - }, - ); + 'by default (without a call to .flattenEntries()) creates an observable of ' + + 'the elements emitted from the DOM Observer', + () => { + class MockDOMObserverEmitsArray extends MockDOMObserver { + observe(...args) { + super.observe(...args); + _rxjsBundlesRxMinJs.Observable.interval(1). + mapTo(['foo', 'bar', 'baz']). + take(2). + subscribe(this._callback); + }} + + + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const output = yield new (_observableDom || _load_observableDom())._DOMObserverObservable( + MockDOMObserverEmitsArray, + 'arg'). + + take(2). + toArray(). + toPromise(); + expect(output).toEqual([['foo', 'bar', 'baz'], ['foo', 'bar', 'baz']]); + })); + }); + describe('multiple subscribers', () => { it('only disconnects the underlying observer when all subscribers have unsubscribed', () => { - const o = new DOMObserverObservable( - MockDOMObserver, - 'some', - 'additional', - { - args: true, - }, - ); + const o = new (_observableDom || _load_observableDom())._DOMObserverObservable( + MockDOMObserver, + 'some', + 'additional', + { + args: true }); + + const subscription = o.subscribe(() => {}); - const subscription2 = o.subscribe(() => {}); + const subscription2 = o.subscribe(() => {});if (!( - invariant(observerInstance != null); + observerInstance != null)) {throw new Error('Invariant violation: "observerInstance != null"');} expect(observerInstance._connected).toBe(true); subscription.unsubscribe(); @@ -129,138 +129,138 @@ describe('new DOMObserverObservable', () => { }); it( - 'creates a new underlying observable and connects it for new' + - 'subscriptions that happen after a disconnect', - () => { - const o = new DOMObserverObservable( - MockDOMObserver, - 'some', - 'additional', - { - args: true, - }, - ); - const subscription = o.subscribe(() => {}); - const subscription2 = o.subscribe(() => {}); - - invariant(observerInstance != null); - const oldObserver = observerInstance; - - subscription.unsubscribe(); - subscription2.unsubscribe(); + 'creates a new underlying observable and connects it for new' + + 'subscriptions that happen after a disconnect', + () => { + const o = new (_observableDom || _load_observableDom())._DOMObserverObservable( + MockDOMObserver, + 'some', + 'additional', + { + args: true }); + + + const subscription = o.subscribe(() => {}); + const subscription2 = o.subscribe(() => {});if (!( + + observerInstance != null)) {throw new Error('Invariant violation: "observerInstance != null"');} + const oldObserver = observerInstance; + + subscription.unsubscribe(); + subscription2.unsubscribe(); + + expect(observerInstance._connected).toBe(false); + const newSubscription = o.subscribe(() => {}); + // creates a new underlying observer + expect(observerInstance).not.toBe(oldObserver); + expect(observerInstance._connected).toBe(true); + newSubscription.unsubscribe(); + }); - expect(observerInstance._connected).toBe(false); - const newSubscription = o.subscribe(() => {}); - // creates a new underlying observer - expect(observerInstance).not.toBe(oldObserver); - expect(observerInstance._connected).toBe(true); - newSubscription.unsubscribe(); - }, - ); }); describe('flattenEntries operator', () => { it('implements lift to cause subsequent operators to return DOMObserverObservables', () => { class MockDOMObserverEmitsArray extends MockDOMObserver { - observe(...args: Array) { + observe(...args) { super.observe(...args); - Observable.interval(1) - .mapTo(['foo', 'bar', 'baz']) - .take(2) - .subscribe(this._callback); - } - } + _rxjsBundlesRxMinJs.Observable.interval(1). + mapTo(['foo', 'bar', 'baz']). + take(2). + subscribe(this._callback); + }} + expect( - new DOMObserverObservable(MockDOMObserverEmitsArray, 'arg') - .flattenEntries() - .map(x => x) instanceof DOMObserverObservable, - ).toBe(true); + new (_observableDom || _load_observableDom())._DOMObserverObservable(MockDOMObserverEmitsArray, 'arg'). + flattenEntries(). + map(x => x) instanceof (_observableDom || _load_observableDom())._DOMObserverObservable). + toBe(true); }); it('creates an observable of the individual elements of the array emitted from the DOM Observer', () => { class MockDOMObserverEmitsArray extends MockDOMObserver { - observe(...args: Array) { + observe(...args) { super.observe(...args); - Observable.interval(1) - .mapTo(['foo', 'bar', 'baz']) - .take(2) - .subscribe(this._callback); - } - } - - waitsForPromise(async () => { - const output = await new DOMObserverObservable( - MockDOMObserverEmitsArray, - 'arg', - ) - .flattenEntries() - .take(6) - .toArray() - .toPromise(); + _rxjsBundlesRxMinJs.Observable.interval(1). + mapTo(['foo', 'bar', 'baz']). + take(2). + subscribe(this._callback); + }} + + + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const output = yield new (_observableDom || _load_observableDom())._DOMObserverObservable( + MockDOMObserverEmitsArray, + 'arg'). + + flattenEntries(). + take(6). + toArray(). + toPromise(); expect(output).toEqual(['foo', 'bar', 'baz', 'foo', 'bar', 'baz']); - }); + })); }); it( - 'creates an observable of the individual elements of the array returned ' + - 'from the getEntries method of the entrylist emitted from the DOM Observer', - () => { - class MockDOMObserverEmitsEntryList extends MockDOMObserver { - observe(...args: Array) { - super.observe(...args); - Observable.interval(1) - .mapTo({ - getEntries: () => ['foo', 'bar', 'baz'], - }) - .take(2) - .subscribe(this._callback); - } - } - - waitsForPromise(async () => { - const output = await new DOMObserverObservable( - MockDOMObserverEmitsEntryList, - 'arg', - ) - .flattenEntries() - .take(6) - .toArray() - .toPromise(); - expect(output).toEqual(['foo', 'bar', 'baz', 'foo', 'bar', 'baz']); - }); - }, - ); + 'creates an observable of the individual elements of the array returned ' + + 'from the getEntries method of the entrylist emitted from the DOM Observer', + () => { + class MockDOMObserverEmitsEntryList extends MockDOMObserver { + observe(...args) { + super.observe(...args); + _rxjsBundlesRxMinJs.Observable.interval(1). + mapTo({ + getEntries: () => ['foo', 'bar', 'baz'] }). + + take(2). + subscribe(this._callback); + }} + + + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const output = yield new (_observableDom || _load_observableDom())._DOMObserverObservable( + MockDOMObserverEmitsEntryList, + 'arg'). + + flattenEntries(). + take(6). + toArray(). + toPromise(); + expect(output).toEqual(['foo', 'bar', 'baz', 'foo', 'bar', 'baz']); + })); + }); + it('throws if neither an iterable nor an EntryList is emitted from the DOM Observer', () => { class MockDOMObserverEmitsNonStandard extends MockDOMObserver { - observe(...args: Array) { + observe(...args) { super.observe(...args); - Observable.interval(1) - .take(2) - .subscribe(this._callback); - } - } + _rxjsBundlesRxMinJs.Observable.interval(1). + take(2). + subscribe(this._callback); + }} + - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { let error; try { - await new DOMObserverObservable( - MockDOMObserverEmitsNonStandard, - 'arg', - ) - .flattenEntries() - .take(2) - .toArray() - .toPromise(); + yield new (_observableDom || _load_observableDom())._DOMObserverObservable( + MockDOMObserverEmitsNonStandard, + 'arg'). + + flattenEntries(). + take(2). + toArray(). + toPromise(); } catch (e) { error = e; - } - invariant(error != null); + }if (!( + error != null)) {throw new Error('Invariant violation: "error != null"');} expect(error.message).toEqual( - 'Tried to merge DOM Observer entries, but they were not iterable nor were they an EntryList.', - ); - }); + 'Tried to merge DOM Observer entries, but they were not iterable nor were they an EntryList.'); + + })); }); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons-ui/spec/openPreview-spec.js b/modules/nuclide-commons-ui/spec/openPreview-spec.js index 1254fd98..a88e77b1 100644 --- a/modules/nuclide-commons-ui/spec/openPreview-spec.js +++ b/modules/nuclide-commons-ui/spec/openPreview-spec.js @@ -1,18 +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 - * @format - */ - -import openPreview from '../openPreview'; -import fsPromise from 'nuclide-commons/fsPromise'; -import nullthrows from 'nullthrows'; +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _openPreview; + + + + + + + + + + + +function _load_openPreview() {return _openPreview = _interopRequireDefault(require('../openPreview'));}var _fsPromise; +function _load_fsPromise() {return _fsPromise = _interopRequireDefault(require('nuclide-commons/fsPromise'));}var _nullthrows; +function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} describe('openPreview', () => { // replace Jasmine's mocked setTimeout with another mock which immediately @@ -31,30 +31,30 @@ describe('openPreview', () => { let file; let fileItem; beforeEach(() => { - waitsForPromise(async () => { - file = await fsPromise.tempfile(); - await fsPromise.writeFile(file, 'foobarbaz\n'.repeat(1000)); - fileItem = await atom.workspace.open(file); - }); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + file = yield (_fsPromise || _load_fsPromise()).default.tempfile(); + yield (_fsPromise || _load_fsPromise()).default.writeFile(file, 'foobarbaz\n'.repeat(1000)); + fileItem = yield atom.workspace.open(file); + })); }); afterEach(() => { - fsPromise.unlink(file); + (_fsPromise || _load_fsPromise()).default.unlink(file); }); it('does not change the cursor position', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { expect(getActiveTextEditor().getURI()).toEqual(file); expect(getActiveTextEditor().getCursorBufferPosition()).toEqual({ row: 0, - column: 0, - }); + column: 0 }); + - await openPreview(file, { + yield (0, (_openPreview || _load_openPreview()).default)(file, { line: 700, column: 3, - center: true, - })._promise; + center: true }). + _promise; // this case shouldn't open any new editors expect(getActiveTextEditor()).toBe(fileItem); @@ -64,9 +64,9 @@ describe('openPreview', () => { expect(getActiveTextEditor().getURI()).toEqual(file); expect(getActiveTextEditor().getCursorBufferPosition()).toEqual({ row: 0, - column: 0, - }); - }); + column: 0 }); + + })); }); }); @@ -75,50 +75,50 @@ describe('openPreview', () => { let previewingFile; beforeEach(() => { - waitsForPromise(async () => { - [startingFile, previewingFile] = await Promise.all([ - fsPromise.tempfile(), - fsPromise.tempfile(), - ]); - await atom.workspace.open(startingFile); - }); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + [startingFile, previewingFile] = yield Promise.all([ + (_fsPromise || _load_fsPromise()).default.tempfile(), + (_fsPromise || _load_fsPromise()).default.tempfile()]); + + yield atom.workspace.open(startingFile); + })); }); afterEach(() => { waitsForPromise(() => - Promise.all([ - fsPromise.unlink(startingFile), - fsPromise.unlink(previewingFile), - ]), - ); + Promise.all([ + (_fsPromise || _load_fsPromise()).default.unlink(startingFile), + (_fsPromise || _load_fsPromise()).default.unlink(previewingFile)])); + + }); it('opens a preview pane editor pointed at the previewFile', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { expect(getActiveTextEditor().getURI()).toEqual(startingFile); expect(getActiveTextEditor().getCursorBufferPosition()).toEqual({ row: 0, - column: 0, - }); + column: 0 }); + - await openPreview(previewingFile)._promise; + yield (0, (_openPreview || _load_openPreview()).default)(previewingFile)._promise; expect(getActiveTextEditor().getURI()).toBe(previewingFile); // $FlowFixMe expect(getPendingItem().getURI()).toBe(previewingFile); - }); + })); }); it('leaves focus on the starting editor', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { expect(getActiveTextEditor().getURI()).toEqual(startingFile); expect(getActiveTextEditor().getCursorBufferPosition()).toEqual({ row: 0, - column: 0, - }); + column: 0 }); - await openPreview(previewingFile)._promise; + + yield (0, (_openPreview || _load_openPreview()).default)(previewingFile)._promise; expect(getActiveTextEditor().getURI()).toEqual(previewingFile); - }); + })); }); }); @@ -128,38 +128,38 @@ describe('openPreview', () => { let secondPreviewingFile; beforeEach(() => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { [ - startingFile, - firstPreviewingFile, - secondPreviewingFile, - ] = await Promise.all([ - fsPromise.tempfile(), - fsPromise.tempfile(), - fsPromise.tempfile(), - ]); - await atom.workspace.open(startingFile); - }); + startingFile, + firstPreviewingFile, + secondPreviewingFile] = + yield Promise.all([ + (_fsPromise || _load_fsPromise()).default.tempfile(), + (_fsPromise || _load_fsPromise()).default.tempfile(), + (_fsPromise || _load_fsPromise()).default.tempfile()]); + + yield atom.workspace.open(startingFile); + })); }); afterEach(() => { waitsForPromise(() => - Promise.all([ - fsPromise.unlink(startingFile), - fsPromise.unlink(firstPreviewingFile), - fsPromise.unlink(secondPreviewingFile), - ]), - ); + Promise.all([ + (_fsPromise || _load_fsPromise()).default.unlink(startingFile), + (_fsPromise || _load_fsPromise()).default.unlink(firstPreviewingFile), + (_fsPromise || _load_fsPromise()).default.unlink(secondPreviewingFile)])); + + }); it('reuses the preview pane when openPreview is called multiple times', () => { - waitsForPromise(async () => { - await openPreview(firstPreviewingFile)._promise; + waitsForPromise((0, _asyncToGenerator.default)(function* () { + yield (0, (_openPreview || _load_openPreview()).default)(firstPreviewingFile)._promise; const firstPendingItem = getPendingItem(); // $FlowFixMe expect(getPendingItem().getURI()).toBe(firstPreviewingFile); - await openPreview(secondPreviewingFile)._promise; + yield (0, (_openPreview || _load_openPreview()).default)(secondPreviewingFile)._promise; const secondPendingItem = getPendingItem(); // $FlowFixMe expect(getPendingItem().getURI()).toBe(secondPreviewingFile); @@ -170,18 +170,18 @@ describe('openPreview', () => { expect(secondPendingItem.isDestroyed()).toBe(false); expect(getPendingItem()).toBe(secondPendingItem); expect(secondPendingItem).toBe(getActiveTextEditor()); - }); + })); }); it('destroys all previews once an openable is confirmed', () => { - waitsForPromise(async () => { - await openPreview(firstPreviewingFile)._promise; + waitsForPromise((0, _asyncToGenerator.default)(function* () { + yield (0, (_openPreview || _load_openPreview()).default)(firstPreviewingFile)._promise; const firstPendingItem = getPendingItem(); - const secondOpenable = openPreview(secondPreviewingFile); - await secondOpenable._promise; + const secondOpenable = (0, (_openPreview || _load_openPreview()).default)(secondPreviewingFile); + yield secondOpenable._promise; const secondPendingItem = getPendingItem(); - await secondOpenable.confirm(); + yield secondOpenable.confirm(); // $FlowFixMe expect(firstPendingItem.isDestroyed()).toBe(true); @@ -189,82 +189,82 @@ describe('openPreview', () => { expect(secondPendingItem.isDestroyed()).toBe(false); expect(getPendingItem()).not.toExist(); expect(secondPendingItem).toBe(getActiveTextEditor()); - }); + })); }); }); it('never reuses a non-pending pane', () => { - waitsForPromise(async () => { - const [startingFile, file1, file2] = await Promise.all([ - fsPromise.tempfile(), - fsPromise.tempfile(), - fsPromise.tempfile(), - ]); - await atom.workspace.open(startingFile); - - await openPreview(file1)._promise; + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const [startingFile, file1, file2] = yield Promise.all([ + (_fsPromise || _load_fsPromise()).default.tempfile(), + (_fsPromise || _load_fsPromise()).default.tempfile(), + (_fsPromise || _load_fsPromise()).default.tempfile()]); + + yield atom.workspace.open(startingFile); + + yield (0, (_openPreview || _load_openPreview()).default)(file1)._promise; // Open a preview back in the originating file, which is not pending - await openPreview(startingFile)._promise; + yield (0, (_openPreview || _load_openPreview()).default)(startingFile)._promise; expect(getActiveTextEditor()).not.toBe(getPendingItem()); // ...and make sure requesting a new preview does *not* reuse the original // file's pane item - await openPreview(file2)._promise; + yield (0, (_openPreview || _load_openPreview()).default)(file2)._promise; expect(getActiveTextEditor()).toBe(getPendingItem()); - await Promise.all([ - fsPromise.unlink(startingFile), - fsPromise.unlink(file1), - fsPromise.unlink(file2), - ]); - }); + yield Promise.all([ + (_fsPromise || _load_fsPromise()).default.unlink(startingFile), + (_fsPromise || _load_fsPromise()).default.unlink(file1), + (_fsPromise || _load_fsPromise()).default.unlink(file2)]); + + })); }); it('throws when trying to confirm a preview that is not the latest', () => { - waitsForPromise(async () => { - const [file1, file2] = await Promise.all([ - fsPromise.tempfile(), - fsPromise.tempfile(), - ]); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const [file1, file2] = yield Promise.all([ + (_fsPromise || _load_fsPromise()).default.tempfile(), + (_fsPromise || _load_fsPromise()).default.tempfile()]); - const preview1 = openPreview(file1); - openPreview(file2); - expect(() => preview1.confirm()).toThrow(); + const preview1 = (0, (_openPreview || _load_openPreview()).default)(file1); + (0, (_openPreview || _load_openPreview()).default)(file2); - await Promise.all([fsPromise.unlink(file1), fsPromise.unlink(file2)]); - }); + expect(function () {return preview1.confirm();}).toThrow(); + + yield Promise.all([(_fsPromise || _load_fsPromise()).default.unlink(file1), (_fsPromise || _load_fsPromise()).default.unlink(file2)]); + })); }); it('throws when calling confirm after cancel', () => { - waitsForPromise(async () => { - const file = await fsPromise.tempfile(); - const preview = openPreview(file); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const file = yield (_fsPromise || _load_fsPromise()).default.tempfile(); + const preview = (0, (_openPreview || _load_openPreview()).default)(file); preview.cancel(); - expect(() => preview.confirm()).toThrow(); + expect(function () {return preview.confirm();}).toThrow(); - await fsPromise.unlink(file); - }); + yield (_fsPromise || _load_fsPromise()).default.unlink(file); + })); }); it('throws when calling cancel after confirm', () => { - waitsForPromise(async () => { - const file = await fsPromise.tempfile(); - const preview = openPreview(file); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const file = yield (_fsPromise || _load_fsPromise()).default.tempfile(); + const preview = (0, (_openPreview || _load_openPreview()).default)(file); preview.confirm(); - expect(() => preview.cancel()).toThrow(); + expect(function () {return preview.cancel();}).toThrow(); - await fsPromise.unlink(file); - }); + yield (_fsPromise || _load_fsPromise()).default.unlink(file); + })); }); -}); - -function getActiveTextEditor(): atom$TextEditor { - return nullthrows(atom.workspace.getActiveTextEditor()); -} - -function getPendingItem(): atom$PaneItem { - return nullthrows( - atom.workspace.paneForItem(getActiveTextEditor()), - ).getPendingItem(); -} +}); /** + * 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. + * + * + * @format + */function getActiveTextEditor() {return (0, (_nullthrows || _load_nullthrows()).default)(atom.workspace.getActiveTextEditor());}function getPendingItem() {return (0, (_nullthrows || _load_nullthrows()).default)(atom.workspace.paneForItem(getActiveTextEditor())).getPendingItem();} \ No newline at end of file diff --git a/modules/nuclide-commons/AbortController.js b/modules/nuclide-commons/AbortController.js index 09437905..7956aab9 100644 --- a/modules/nuclide-commons/AbortController.js +++ b/modules/nuclide-commons/AbortController.js @@ -1,59 +1,58 @@ -/** - * 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 - * @format - */ - -/** - * This implements polyfills for AbortSignal and AbortController - * from the whatwg spec: https://dom.spec.whatwg.org/#aborting-ongoing-activities - * These will become available in Chrome 66. - */ - -// Shim of EventTarget usable in Node. -// Note that even in Chrome, EventTarget also isn't instantiable until version 64. -import { - EventTarget as EventTargetShim, - defineEventAttribute, -} from 'event-target-shim'; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.AbortSignal = undefined;var _eventTargetShim; + + + + + + + + + + + + + + -export class AbortSignal extends (EventTargetShim: typeof EventTarget) { - aborted: boolean = false; + + + + +function _load_eventTargetShim() {return _eventTargetShim = require('event-target-shim');} + + + + +class AbortSignal extends (_eventTargetShim || _load_eventTargetShim()).EventTarget {constructor(...args) {var _temp;return _temp = super(...args), this. + aborted = false, _temp;} // Defined via defineEventAttribute below. - onabort: ?(event: Event) => mixed; + // $FlowIssue: Computed properties are not supported get [Symbol.toStringTag]() { return 'AbortSignal'; - } -} - -defineEventAttribute(AbortSignal.prototype, 'abort'); - -export default class AbortController { - signal = new AbortSignal(); - - abort() { - // From whatwg spec, section 3.2: + }}exports.AbortSignal = AbortSignal; /** + * 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. + * + * + * @format + */ /** + * This implements polyfills for AbortSignal and AbortController + * from the whatwg spec: https://dom.spec.whatwg.org/#aborting-ongoing-activities + * These will become available in Chrome 66. + */ // Shim of EventTarget usable in Node. +// Note that even in Chrome, EventTarget also isn't instantiable until version 64. +(0, (_eventTargetShim || _load_eventTargetShim()).defineEventAttribute)(AbortSignal.prototype, 'abort');class AbortController {constructor() {this.signal = new AbortSignal();}abort() {// From whatwg spec, section 3.2: // If signal’s aborted flag is set, then return. - if (this.signal.aborted) { - return; - } - // Set signal’s aborted flag. - this.signal.aborted = true; - // Fire an event named abort at signal. + if (this.signal.aborted) {return;} // Set signal’s aborted flag. + this.signal.aborted = true; // Fire an event named abort at signal. // Note: event-target-shim converts objects to Events. - this.signal.dispatchEvent(({type: 'abort'}: any)); - } - - // $FlowIssue: Computed properties are not supported + this.signal.dispatchEvent({ type: 'abort' });} // $FlowIssue: Computed properties are not supported get [Symbol.toStringTag]() { return 'AbortController'; - } -} + }}exports.default = AbortController; \ No newline at end of file diff --git a/modules/nuclide-commons/BatchProcessedQueue.js b/modules/nuclide-commons/BatchProcessedQueue.js index 962e6570..c8348895 100644 --- a/modules/nuclide-commons/BatchProcessedQueue.js +++ b/modules/nuclide-commons/BatchProcessedQueue.js @@ -1,33 +1,33 @@ -/** - * 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 - * @format - */ - -export type BatchHandler = (batch: Array) => void; +"use strict";Object.defineProperty(exports, "__esModule", { value: true }); + + + + + + + + + + + + // A Queue which will process elements at intervals, only if the // queue contains any elements. -export default class BatchProcessedQueue { - _batchPeriod: number; - _handler: BatchHandler; - _timeoutId: ?TimeoutID; - _items: Array; +class BatchProcessedQueue { + - constructor(batchPeriod: number, handler: BatchHandler) { + + + + constructor(batchPeriod, handler) { this._batchPeriod = batchPeriod; this._handler = handler; this._timeoutId = null; this._items = []; } - add(item: T): void { + add(item) { this._items.push(item); // eslint-disable-next-line eqeqeq if (this._timeoutId === null) { @@ -44,11 +44,20 @@ export default class BatchProcessedQueue { this._handler(batch); } - dispose(): void { + dispose() { // eslint-disable-next-line eqeqeq if (this._timeoutId !== null) { clearTimeout(this._timeoutId); this._handleBatch(); } - } -} + }}exports.default = BatchProcessedQueue; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/ConfigCache.js b/modules/nuclide-commons/ConfigCache.js index f4ddbddc..7f7cac48 100644 --- a/modules/nuclide-commons/ConfigCache.js +++ b/modules/nuclide-commons/ConfigCache.js @@ -1,41 +1,41 @@ -/** - * 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 - * @format - */ - -import type {LRUCache} from 'lru-cache'; -import type {NuclideUri} from './nuclideUri'; - -import LRU from 'lru-cache'; -import fsPromise from './fsPromise'; - -export type SearchStrategy = 'nearest' | 'furthest' | 'priority'; - -export class ConfigCache { - _configFileNames: Array; - _searchStrategy: SearchStrategy; - _configCache: LRUCache>; - - constructor( - configFileNames: Array, - searchStrategy?: SearchStrategy = 'nearest', - ) { +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.ConfigCache = undefined;var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _lruCache; + + + + + + + + + + + + + + +function _load_lruCache() {return _lruCache = _interopRequireDefault(require('lru-cache'));}var _fsPromise; +function _load_fsPromise() {return _fsPromise = _interopRequireDefault(require('./fsPromise'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */class ConfigCache {constructor(configFileNames, + searchStrategy = 'nearest') + { this._configFileNames = configFileNames; this._searchStrategy = searchStrategy; - this._configCache = LRU({ + this._configCache = (0, (_lruCache || _load_lruCache()).default)({ max: 200, // Want this to exceed the maximum expected number of open files + dirs. - maxAge: 1000 * 30, // 30 seconds + maxAge: 1000 * 30 // 30 seconds }); } - getConfigDir(path: NuclideUri): Promise { + getConfigDir(path) { let result = this._configCache.get(path); if (result == null) { result = this._findConfigDir(path); @@ -44,39 +44,38 @@ export class ConfigCache { return result; } - async _findConfigDir(path: NuclideUri): Promise { - const configDirs = await Promise.all( - this._configFileNames.map(configFile => { - if (this._searchStrategy === 'furthest') { - return fsPromise.findFurthestFile(configFile, path); + _findConfigDir(path) {var _this = this;return (0, _asyncToGenerator.default)(function* () { + const configDirs = yield Promise.all( + _this._configFileNames.map(function (configFile) { + if (_this._searchStrategy === 'furthest') { + return (_fsPromise || _load_fsPromise()).default.findFurthestFile(configFile, path); } else { - return fsPromise.findNearestFile(configFile, path); - } - }), - ); - - if (this._searchStrategy === 'nearest') { - // Find the result with the greatest length (the closest match). - return configDirs.filter(Boolean).reduce((previous, configDir) => { - if (previous == null || configDir.length > previous.length) { - return configDir; + return (_fsPromise || _load_fsPromise()).default.findNearestFile(configFile, path); } - return previous; - }, null); - } else if (this._searchStrategy === 'furthest') { - return configDirs.filter(Boolean).reduce((previous, configDir) => { - if (previous == null || configDir.length < previous.length) { - return configDir; - } - return previous; - }, null); - } else { - // Find the first match. - return configDirs.find(Boolean); - } + })); + + + if (_this._searchStrategy === 'nearest') { + // Find the result with the greatest length (the closest match). + return configDirs.filter(Boolean).reduce(function (previous, configDir) { + if (previous == null || configDir.length > previous.length) { + return configDir; + } + return previous; + }, null); + } else if (_this._searchStrategy === 'furthest') { + return configDirs.filter(Boolean).reduce(function (previous, configDir) { + if (previous == null || configDir.length < previous.length) { + return configDir; + } + return previous; + }, null); + } else { + // Find the first match. + return configDirs.find(Boolean); + }})(); } - dispose(): void { + dispose() { this._configCache.reset(); - } -} + }}exports.ConfigCache = ConfigCache; \ No newline at end of file diff --git a/modules/nuclide-commons/Hasher.js b/modules/nuclide-commons/Hasher.js index 5704bc0e..bd1b944b 100644 --- a/modules/nuclide-commons/Hasher.js +++ b/modules/nuclide-commons/Hasher.js @@ -1,62 +1,62 @@ -/** - * 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 - * @format - */ +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); /** + * 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. + * + * + * @format + */ /** - * Get a hash for the provider object. Hashes are unique per-hasher, so if you have two different - * hashers, there is no guarantee that they will give the same hash for the same object. - * - * One use case for this is with lists of React elements. Just create a hasher and use the hash as - * a key: - * - * class MyComponent extends React.Component { - * constructor(props) { - * super(props); - * this._hasher = new Hasher(); - * } - * render() { - * return this.props.items.map(item => ( - * - * )); - * } - * } - */ -export default class Hasher { - _hashes: WeakMap; - _objectCount: number; + * Get a hash for the provider object. Hashes are unique per-hasher, so if you have two different + * hashers, there is no guarantee that they will give the same hash for the same object. + * + * One use case for this is with lists of React elements. Just create a hasher and use the hash as + * a key: + * + * class MyComponent extends React.Component { + * constructor(props) { + * super(props); + * this._hasher = new Hasher(); + * } + * render() { + * return this.props.items.map(item => ( + * + * )); + * } + * } + */ +class Hasher { + + constructor() { this._hashes = new WeakMap(); this._objectCount = 0; } - getHash(item: K): string | number { + getHash(item) { // eslint-disable-next-line eqeqeq if (item === null) { return 'null'; } const type = typeof item; switch (typeof item) { - case 'object': { - let hash = this._hashes.get(item); - if (hash == null) { - hash = `${type}:${this._objectCount}`; - this._hashes.set(item, hash); - this._objectCount = - this._objectCount + 1 === Number.MAX_SAFE_INTEGER - ? Number.MIN_SAFE_INTEGER - : this._objectCount + 1; + case 'object':{ + let hash = this._hashes.get(item); + if (hash == null) { + hash = `${type}:${this._objectCount}`; + this._hashes.set(item, hash); + this._objectCount = + this._objectCount + 1 === Number.MAX_SAFE_INTEGER ? + Number.MIN_SAFE_INTEGER : + this._objectCount + 1; + } + return hash; } - return hash; - } case 'undefined': return 'undefined'; case 'string': @@ -65,7 +65,6 @@ export default class Hasher { case 'number': return item; default: - throw new Error('Unhashable object'); - } - } -} + throw new Error('Unhashable object');} + + }}exports.default = Hasher; \ No newline at end of file diff --git a/modules/nuclide-commons/Model.js b/modules/nuclide-commons/Model.js index ff3a12e7..e8641b0f 100644 --- a/modules/nuclide-commons/Model.js +++ b/modules/nuclide-commons/Model.js @@ -1,78 +1,87 @@ -/** - * 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 - * @format - */ - -import type {Observable} from 'rxjs'; - -import {BehaviorSubject} from 'rxjs'; -import UniversalDisposable from './UniversalDisposable'; +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); + + + + + + + + + + + + + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('./UniversalDisposable'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** - * Exposes a simple API for a stateful model. This is similar to React's `state`/`setState()` API - * except achieved via composition and easily convertible to observables so you can do awesome - * stuff. It's really a super-thin wrapper around `BehaviorSubject`; wrapping `BehaviorSubject` - * instead of extending it was done to minimize the API surface area. Ideally, this would implement - * `Symbol.observable` instead of having a `toObservable()` method, but since Flow doesn't - * understand that, it causes more trouble than it's worth. - * - * While you can extend this class, composition is recommended. - * - * Example: - * - * class MyThing { - * _model = new Model({count: 0}); - * increment(): void { - * const {count} = this._model.state; - * this._model.setState({count: count + 1}); - * } - * } - * - * BEST PRACTICES - * - * Don't pass your model instance around! Instead, create a new object with the properties you want - * and explicit setters: - * - * const props = { - * count: model.state.count, - * increment: () => { - * const {count} = model.state; - * model.setState({count: count + 1}) - * }, - * }; - * - * You'll notice that this is very similar to Flux/Redux, with the setters corresponding to bound - * action creators. That's awesome! It means that, should the state grow and require new - * capabilities, we can always switch to full-blown Redux without having to refactor a ton of stuff. - */ -export default class Model { - _states: BehaviorSubject; - - constructor(initialState: State) { - this._states = new BehaviorSubject(initialState); + * Exposes a simple API for a stateful model. This is similar to React's `state`/`setState()` API + * except achieved via composition and easily convertible to observables so you can do awesome + * stuff. It's really a super-thin wrapper around `BehaviorSubject`; wrapping `BehaviorSubject` + * instead of extending it was done to minimize the API surface area. Ideally, this would implement + * `Symbol.observable` instead of having a `toObservable()` method, but since Flow doesn't + * understand that, it causes more trouble than it's worth. + * + * While you can extend this class, composition is recommended. + * + * Example: + * + * class MyThing { + * _model = new Model({count: 0}); + * increment(): void { + * const {count} = this._model.state; + * this._model.setState({count: count + 1}); + * } + * } + * + * BEST PRACTICES + * + * Don't pass your model instance around! Instead, create a new object with the properties you want + * and explicit setters: + * + * const props = { + * count: model.state.count, + * increment: () => { + * const {count} = model.state; + * model.setState({count: count + 1}) + * }, + * }; + * + * You'll notice that this is very similar to Flux/Redux, with the setters corresponding to bound + * action creators. That's awesome! It means that, should the state grow and require new + * capabilities, we can always switch to full-blown Redux without having to refactor a ton of stuff. + */ +class Model { + + + constructor(initialState) { + this._states = new _rxjsBundlesRxMinJs.BehaviorSubject(initialState); } - setState(newState: $Shape): void { - const nextState = {...this.state, ...newState}; + setState(newState) { + const nextState = Object.assign({}, this.state, newState); this._states.next(nextState); } - get state(): State { + get state() { return this._states.getValue(); } - subscribe(cb: (state: State) => mixed): IDisposable { - return new UniversalDisposable(this.toObservable().subscribe({next: cb})); + subscribe(cb) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(this.toObservable().subscribe({ next: cb })); } - toObservable(): Observable { + toObservable() { return this._states.distinctUntilChanged(); - } -} + }}exports.default = Model; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/ObservablePool.js b/modules/nuclide-commons/ObservablePool.js index 3b0807ab..a585140a 100644 --- a/modules/nuclide-commons/ObservablePool.js +++ b/modules/nuclide-commons/ObservablePool.js @@ -1,74 +1,74 @@ -/** - * 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 - * @format - */ +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); + + + + + + + + + + + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + + + + + -import {Observable, Subject} from 'rxjs'; -type Executor = Observable | (() => rxjs$ObservableInput); -type Request = {tag: mixed, executor: Executor}; -type Response = { - observer: rxjs$Observer, - unsubscribed: Subject, -}; /** - * ObservablePool allows you to execute Observables or functions that return - * Observable inputs (i.e. Observables, Promises, or Iterables) - * with a concurrency limit. - * - * Execution requests are queued and unsubscriptions are forwarded through - * (if a request is still on the queue, its execution will be cancelled.) - * - * For requests that return a Promise, the ObservablePool is pessimistic - * and assumes that the operation is uncancellable - it will not remove - * the execution from the pool until it resolves or rejects. However - * `schedule()` will still return an Observable to enable the use case - * of cancelling requests while they're in the queue. - * - * Example: - * - * const pool = new ObservablePool(2); - * pool - * .schedule(Observable.timer(1000).mapTo(1)) - * .subscribe(console.log); - * Observable.timer(1000) - * .mapTo(2) - * .let(pool.schedule.bind(pool)) - * .subscribe(console.log); - * pool - * .schedule(Observable.timer(100).mapTo(3)) - * .subscribe(console.log); - * - * The output here is 1, 2, then 3. Despite the fact that the third observable - * finishes more quickly, its execution is postponed until the first two finish. - */ -export default class ObservablePool { - _requests: Subject>; - _responseListeners: Map>; - _subscription: rxjs$ISubscription; - - constructor(concurrency: number) { - this._requests = new Subject(); + * ObservablePool allows you to execute Observables or functions that return + * Observable inputs (i.e. Observables, Promises, or Iterables) + * with a concurrency limit. + * + * Execution requests are queued and unsubscriptions are forwarded through + * (if a request is still on the queue, its execution will be cancelled.) + * + * For requests that return a Promise, the ObservablePool is pessimistic + * and assumes that the operation is uncancellable - it will not remove + * the execution from the pool until it resolves or rejects. However + * `schedule()` will still return an Observable to enable the use case + * of cancelling requests while they're in the queue. + * + * Example: + * + * const pool = new ObservablePool(2); + * pool + * .schedule(Observable.timer(1000).mapTo(1)) + * .subscribe(console.log); + * Observable.timer(1000) + * .mapTo(2) + * .let(pool.schedule.bind(pool)) + * .subscribe(console.log); + * pool + * .schedule(Observable.timer(100).mapTo(3)) + * .subscribe(console.log); + * + * The output here is 1, 2, then 3. Despite the fact that the third observable + * finishes more quickly, its execution is postponed until the first two finish. + */ +class ObservablePool { + + + + + constructor(concurrency) { + this._requests = new _rxjsBundlesRxMinJs.Subject(); this._responseListeners = new Map(); this._subscription = this._handleEvents(concurrency); } - schedule(executor: Executor): Observable { - return Observable.create(observer => { - const unsubscribed = new Subject(); + schedule(executor) { + return _rxjsBundlesRxMinJs.Observable.create(observer => { + const unsubscribed = new _rxjsBundlesRxMinJs.Subject(); const tag = {}; // Just a unique object. - this._responseListeners.set(tag, {observer, unsubscribed}); - this._requests.next({tag, executor}); + this._responseListeners.set(tag, { observer, unsubscribed }); + this._requests.next({ tag, executor }); return () => { this._responseListeners.delete(tag); unsubscribed.next(); @@ -77,56 +77,65 @@ export default class ObservablePool { } /** - * Warning: calling dispose() will error all executing requests. - */ + * Warning: calling dispose() will error all executing requests. + */ dispose() { - this._responseListeners.forEach(({observer}) => { + this._responseListeners.forEach(({ observer }) => { observer.error(Error('ObservablePool was disposed')); }); this._subscription.unsubscribe(); } - _handleEvents(concurrency: number): rxjs$ISubscription { - return this._requests - .mergeMap(event => { - const {executor, tag} = event; - const listener = this._responseListeners.get(tag); - // unsubscribed before we could even get to it! - if (listener == null) { - return Observable.empty(); - } - const {observer, unsubscribed} = listener; - let result; - if (executor instanceof Observable) { - result = executor; - } else { - try { - result = executor(); - } catch (err) { - // Catch errors from executor(). - observer.error(err); - return Observable.empty(); - } - } - if (result instanceof Observable) { - // We can safely forward unsubscriptions! - return ( - result - .takeUntil(unsubscribed) - // $FlowFixMe: Flow doesn't like this. - .do(observer) - .catch(() => Observable.empty()) - ); - } else { - // In the absence of cancellation, assume the worst. - return ( - Observable.from(result) - // $FlowFixMe: Flow doesn't like this. - .do(observer) - .catch(() => Observable.empty()) - ); + _handleEvents(concurrency) { + return this._requests. + mergeMap(event => { + const { executor, tag } = event; + const listener = this._responseListeners.get(tag); + // unsubscribed before we could even get to it! + if (listener == null) { + return _rxjsBundlesRxMinJs.Observable.empty(); + } + const { observer, unsubscribed } = listener; + let result; + if (executor instanceof _rxjsBundlesRxMinJs.Observable) { + result = executor; + } else { + try { + result = executor(); + } catch (err) { + // Catch errors from executor(). + observer.error(err); + return _rxjsBundlesRxMinJs.Observable.empty(); } - }, concurrency) - .subscribe(); - } -} + } + if (result instanceof _rxjsBundlesRxMinJs.Observable) { + // We can safely forward unsubscriptions! + return ( + result. + takeUntil(unsubscribed) + // $FlowFixMe: Flow doesn't like this. + .do(observer). + catch(() => _rxjsBundlesRxMinJs.Observable.empty())); + + } else { + // In the absence of cancellation, assume the worst. + return ( + _rxjsBundlesRxMinJs.Observable.from(result) + // $FlowFixMe: Flow doesn't like this. + .do(observer). + catch(() => _rxjsBundlesRxMinJs.Observable.empty())); + + } + }, concurrency). + subscribe(); + }}exports.default = ObservablePool; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/SafeStreamMessageReader.js b/modules/nuclide-commons/SafeStreamMessageReader.js index a105eb46..59e28e6a 100644 --- a/modules/nuclide-commons/SafeStreamMessageReader.js +++ b/modules/nuclide-commons/SafeStreamMessageReader.js @@ -1,26 +1,26 @@ -/** - * 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 - * @format - */ - -import {StreamMessageReader} from 'vscode-jsonrpc'; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _vscodeJsonrpc; + + + + + + + + + + + +function _load_vscodeJsonrpc() {return _vscodeJsonrpc = require('vscode-jsonrpc');} /** - * vscode-jsonrpc's StreamMessageReader has a fatal flaw of throwing exceptions! - * It's hard to catch asynchronous exceptions, and it crashes the Nuclide server. - * Until this is addressed, this captures exceptions and emits errors instead. - * - * https://github.com/Microsoft/vscode-languageserver-node/issues/270 - */ -export default class SafeStreamMessageReader extends StreamMessageReader { - onData(data: Buffer | string) { + * vscode-jsonrpc's StreamMessageReader has a fatal flaw of throwing exceptions! + * It's hard to catch asynchronous exceptions, and it crashes the Nuclide server. + * Until this is addressed, this captures exceptions and emits errors instead. + * + * https://github.com/Microsoft/vscode-languageserver-node/issues/270 + */ +class SafeStreamMessageReader extends (_vscodeJsonrpc || _load_vscodeJsonrpc()).StreamMessageReader { + onData(data) { try { super.onData(data); } catch (err) { @@ -30,5 +30,14 @@ export default class SafeStreamMessageReader extends StreamMessageReader { this.dispose(); this.readable.removeAllListeners(); } - } -} + }}exports.default = SafeStreamMessageReader; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/UniversalDisposable.js b/modules/nuclide-commons/UniversalDisposable.js index 65836a52..cdf96d34 100644 --- a/modules/nuclide-commons/UniversalDisposable.js +++ b/modules/nuclide-commons/UniversalDisposable.js @@ -1,26 +1,26 @@ -/** - * 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 - * @format - */ - -export type AnyTeardown = (() => mixed) | rxjs$ISubscription | IDisposable; +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); + + + + + + + + + + + + /** - * Like a CompositeDisposable, but in addition to Disposable instances it can - * also accept plain functions and Rx subscriptions. - */ -export default class UniversalDisposable { - disposed: boolean; - teardowns: Set; - - constructor(...teardowns: Array) { + * Like a CompositeDisposable, but in addition to Disposable instances it can + * also accept plain functions and Rx subscriptions. + */ +class UniversalDisposable { + + + + constructor(...teardowns) { this.teardowns = new Set(); this.disposed = false; if (teardowns.length) { @@ -28,7 +28,7 @@ export default class UniversalDisposable { } } - add(...teardowns: Array): void { + add(...teardowns) { if (this.disposed) { throw new Error('Cannot add to an already disposed UniversalDisposable!'); } @@ -38,13 +38,13 @@ export default class UniversalDisposable { } } - remove(teardown: AnyTeardown): void { + remove(teardown) { if (!this.disposed) { this.teardowns.delete(teardown); } } - dispose(): void { + dispose() { if (!this.disposed) { this.disposed = true; this.teardowns.forEach(teardown => { @@ -56,30 +56,30 @@ export default class UniversalDisposable { teardown(); } }); - this.teardowns = (null: any); + this.teardowns = null; } } - unsubscribe(): void { + unsubscribe() { this.dispose(); } - clear(): void { + clear() { if (!this.disposed) { this.teardowns.clear(); } - } -} - -function assertTeardown(teardown: AnyTeardown): void { - if ( - typeof teardown.dispose === 'function' || - typeof teardown.unsubscribe === 'function' || - typeof teardown === 'function' - ) { - return; - } + }}exports.default = UniversalDisposable; /** + * 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. + * + * + * @format + */function assertTeardown(teardown) {if (typeof teardown.dispose === 'function' || typeof teardown.unsubscribe === 'function' || typeof teardown === 'function') {return;} throw new TypeError( - 'Arguments to UniversalDisposable.add must be disposable', - ); -} + 'Arguments to UniversalDisposable.add must be disposable'); + +} \ No newline at end of file diff --git a/modules/nuclide-commons/analytics.js b/modules/nuclide-commons/analytics.js index ba1aaa6e..6b779186 100644 --- a/modules/nuclide-commons/analytics.js +++ b/modules/nuclide-commons/analytics.js @@ -1,218 +1,248 @@ -/** - * 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 - * @format - */ - -import type {Observable} from 'rxjs'; - -import UniversalDisposable from './UniversalDisposable'; -import {isPromise} from './promise'; -import performanceNow from './performanceNow'; - -export type RawAnalyticsService = { - track( - eventName: string, - values?: {[key: string]: mixed}, - immediate?: boolean, - ): ?Promise, - isTrackSupported: () => boolean, -}; - -let rawAnalyticsService: RawAnalyticsService = { - track(): ?Promise {}, - isTrackSupported: () => false, -}; - -export type TrackingEvent = { - type: string, - data?: Object, -}; - -export type TrackEvent = { - key: string, - values: {[key: string]: mixed}, -}; - -/** - * Track a set of values against a named event. - * Analytics will be batched and processed asynchronously in the background. - * - * @param eventName Name of the event to be tracked. - * @param values The object containing the data to track. - */ -export function track( - eventName: string, - values?: {[key: string]: mixed}, -): void { - rawAnalyticsService.track(eventName, values || {}); -} - -export function isTrackSupported(): boolean { - return rawAnalyticsService.isTrackSupported(); -} - -/** - * Same as `track`, except this is guaranteed to send immediately. - * The returned promise will resolve when the request completes (or reject on failure). - */ -export function trackImmediate( - eventName: string, - values?: {[key: string]: mixed}, -): Promise { - return ( - rawAnalyticsService.track(eventName, values || {}, true) || - Promise.resolve() - ); -} - -/** - * An alternative interface for `track` that accepts a single event object. This is particularly - * useful when dealing with streams (Observables). - */ -export function trackEvent(event: TrackingEvent): void { - track(event.type, event.data); -} - -/** - * Track each event in a stream of TrackingEvents. - */ -export function trackEvents(events: Observable): IDisposable { - return new UniversalDisposable(events.subscribe(trackEvent)); -} - -/** - * A sampled version of track that only tracks every 1/sampleRate calls. - */ -export function trackSampled( - eventName: string, - sampleRate: number, - values?: {[key: string]: mixed}, -): void { - if (Math.random() * sampleRate <= 1) { - rawAnalyticsService.track(eventName, values || {}); - } -} - -const PERFORMANCE_EVENT = 'performance'; -const canMeasure = typeof performance !== 'undefined'; -export class TimingTracker { - static eventCount = 0; - - _eventName: string; - _startTime: number; - _startMark: string; - _values: {[key: string]: mixed}; - - constructor(eventName: string, values: {[key: string]: mixed}) { - this._eventName = eventName; - this._startMark = `${this._eventName}_${TimingTracker.eventCount++}_start`; - this._startTime = performanceNow(); - this._values = values; - if (canMeasure) { - // eslint-disable-next-line no-undef - performance.mark(this._startMark); - } - } - - onError(error: Error): void { - this._trackTimingEvent(error); - } - - onSuccess(): void { - this._trackTimingEvent(/* error */ null); - } - - _trackTimingEvent(exception: ?Error): void { - if (canMeasure) { - /* eslint-disable no-undef */ - // call measure to add this information to the devtools timeline in the +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.TimingTracker = undefined;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +track = track;exports. + + + + + + +isTrackSupported = isTrackSupported;exports. + + + + + + + +trackImmediate = trackImmediate;exports. + + + + + + + + + + + + + +trackEvent = trackEvent;exports. + + + + + + +trackEvents = trackEvents;exports. + + + + + + +trackSampled = trackSampled;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +startTracking = startTracking;exports. + + + + + + + + + + + + + + + +trackTiming = trackTiming;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +setRawAnalyticsService = setRawAnalyticsService;var _UniversalDisposable;function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('./UniversalDisposable'));}var _promise;function _load_promise() {return _promise = require('./promise');}var _performanceNow;function _load_performanceNow() {return _performanceNow = _interopRequireDefault(require('./performanceNow'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */let rawAnalyticsService = { track() {}, isTrackSupported: () => false }; /** + * Track a set of values against a named event. + * Analytics will be batched and processed asynchronously in the background. + * + * @param eventName Name of the event to be tracked. + * @param values The object containing the data to track. + */function track(eventName, values) {rawAnalyticsService.track(eventName, values || {});}function isTrackSupported() {return rawAnalyticsService.isTrackSupported();} /** + * Same as `track`, except this is guaranteed to send immediately. + * The returned promise will resolve when the request completes (or reject on failure). + */function trackImmediate(eventName, values) {return rawAnalyticsService.track(eventName, values || {}, true) || Promise.resolve();} /** + * An alternative interface for `track` that accepts a single event object. This is particularly + * useful when dealing with streams (Observables). + */function trackEvent(event) {track(event.type, event.data);} /** + * Track each event in a stream of TrackingEvents. + */function trackEvents(events) {return new (_UniversalDisposable || _load_UniversalDisposable()).default(events.subscribe(trackEvent));} /** + * A sampled version of track that only tracks every 1/sampleRate calls. + */function trackSampled(eventName, sampleRate, values) {if (Math.random() * sampleRate <= 1) {rawAnalyticsService.track(eventName, values || {});}}const PERFORMANCE_EVENT = 'performance';const canMeasure = typeof performance !== 'undefined';class TimingTracker {constructor(eventName, values) {this._eventName = eventName;this._startMark = `${this._eventName}_${TimingTracker.eventCount++}_start`;this._startTime = (0, (_performanceNow || _load_performanceNow()).default)();this._values = values;if (canMeasure) {// eslint-disable-next-line no-undef + performance.mark(this._startMark);}}onError(error) {this._trackTimingEvent(error);}onSuccess() {this._trackTimingEvent( /* error */null);}_trackTimingEvent(exception) {if (canMeasure) {/* eslint-disable no-undef */ // call measure to add this information to the devtools timeline in the // case the profiler is running. - performance.measure(this._eventName, this._startMark); - // then clear all the marks and measurements to avoid growing the + performance.measure(this._eventName, this._startMark); // then clear all the marks and measurements to avoid growing the // performance entry buffer - performance.clearMarks(this._startMark); - performance.clearMeasures(this._eventName); - /* eslint-enable no-undef */ - } - - track(PERFORMANCE_EVENT, { - ...this._values, - duration: Math.round(performanceNow() - this._startTime).toString(), - eventName: this._eventName, - error: exception ? '1' : '0', - exception: exception ? exception.toString() : '', - }); - } -} - -export function startTracking( - eventName: string, - values?: {[key: string]: any} = {}, -): TimingTracker { - return new TimingTracker(eventName, values); -} - -/** - * Reports analytics including timing for a single operation. - * - * Usage: - * - * analytics.trackTiming('my-package-some-long-operation' () => doit()); - * - * Returns (or throws) the result of the operation. - */ -export function trackTiming( - eventName: string, - operation: () => T, - values?: {[key: string]: any} = {}, -): T { - const tracker = startTracking(eventName, values); - - try { - const result = operation(); - - if (isPromise(result)) { - // Atom uses a different Promise implementation than Nuclide, so the following is not true: + performance.clearMarks(this._startMark);performance.clearMeasures(this._eventName); /* eslint-enable no-undef */}track(PERFORMANCE_EVENT, Object.assign({}, this._values, { duration: Math.round((0, (_performanceNow || _load_performanceNow()).default)() - this._startTime).toString(), eventName: this._eventName, error: exception ? '1' : '0', exception: exception ? exception.toString() : '' }));}}exports.TimingTracker = TimingTracker;TimingTracker.eventCount = 0;function startTracking(eventName, values = {}) {return new TimingTracker(eventName, values);} /** + * Reports analytics including timing for a single operation. + * + * Usage: + * + * analytics.trackTiming('my-package-some-long-operation' () => doit()); + * + * Returns (or throws) the result of the operation. + */function trackTiming(eventName, operation, values = {}) {const tracker = startTracking(eventName, values);try {const result = operation();if ((0, (_promise || _load_promise()).isPromise)(result)) {// Atom uses a different Promise implementation than Nuclide, so the following is not true: // invariant(result instanceof Promise); - // For the method returning a Promise, track the time after the promise is resolved/rejected. - return (result: any).then( - value => { - tracker.onSuccess(); - return value; - }, - reason => { - tracker.onError(reason instanceof Error ? reason : new Error(reason)); - return Promise.reject(reason); - }, - ); - } else { - tracker.onSuccess(); - return result; - } - } catch (error) { - tracker.onError(error); - throw error; - } -} - -export function setRawAnalyticsService( - analyticsService: RawAnalyticsService, -): void { - rawAnalyticsService = analyticsService; -} - -export default { - track, - trackEvent, - trackTiming, - startTracking, - TimingTracker, -}; + return result.then(value => {tracker.onSuccess();return value;}, reason => {tracker.onError(reason instanceof Error ? reason : new Error(reason));return Promise.reject(reason);});} else {tracker.onSuccess();return result;}} catch (error) {tracker.onError(error);throw error;}}function setRawAnalyticsService(analyticsService) {rawAnalyticsService = analyticsService;}exports.default = { track, trackEvent, trackTiming, startTracking, TimingTracker }; \ No newline at end of file diff --git a/modules/nuclide-commons/cache.js b/modules/nuclide-commons/cache.js index 9a182061..e31dc04f 100644 --- a/modules/nuclide-commons/cache.js +++ b/modules/nuclide-commons/cache.js @@ -1,39 +1,39 @@ -/** - * 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 - * @format - */ +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.DISPOSE_VALUE = exports.Cache = undefined; + + + + + + + + + -import {Observable, Subject} from 'rxjs'; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); // A Cache mapping keys to values which creates entries as they are requested. -export class Cache { - _values: Map; - _factory: (key: KeyType) => ValueType; - _disposeValue: (value: ValueType) => mixed; - _entriesSubject: Subject<[KeyType, ValueType]>; +class Cache { + + + + constructor( - factory: (key: KeyType) => ValueType, - disposeValue: (value: ValueType) => mixed = value => {}, - ) { + factory, + disposeValue = value => {}) + { this._values = new Map(); this._factory = factory; this._disposeValue = disposeValue; - this._entriesSubject = new Subject(); + this._entriesSubject = new _rxjsBundlesRxMinJs.Subject(); } - has(key: KeyType): boolean { + has(key) { return this._values.has(key); } - get(key: KeyType): ValueType { + get(key) { if (!this._values.has(key)) { const newValue = this._factory(key); this._values.set(key, newValue); @@ -41,14 +41,14 @@ export class Cache { return newValue; } else { // Cannot use invariant as ValueType may include null/undefined. - return (this._values.get(key): any); + return this._values.get(key); } } // After this method this._values.keys() === newKeys. // deletes all keys not in newKeys // gets all keys in newKeys - setKeys(newKeys: Set): void { + setKeys(newKeys) { for (const existingKey of this._values.keys()) { if (!newKeys.has(existingKey)) { this.delete(existingKey); @@ -60,34 +60,34 @@ export class Cache { } } - entries(): Iterator<[KeyType, ValueType]> { + entries() { return this._values.entries(); } - keys(): Iterator { + keys() { return this._values.keys(); } - values(): Iterator { + values() { return this._values.values(); } - observeValues(): Observable { + observeValues() { return this.observeEntries().map(entry => entry[1]); } - observeEntries(): Observable<[KeyType, ValueType]> { - return Observable.concat( - Observable.from(this._values.entries()), - this._entriesSubject, - ); + observeEntries() { + return _rxjsBundlesRxMinJs.Observable.concat( + _rxjsBundlesRxMinJs.Observable.from(this._values.entries()), + this._entriesSubject); + } - observeKeys(): Observable { + observeKeys() { return this.observeEntries().map(entry => entry[0]); } - delete(key: KeyType): boolean { + delete(key) { if (this.has(key)) { const value = this.get(key); this._values.delete(key); @@ -98,7 +98,7 @@ export class Cache { } } - clear(): void { + clear() { // Defend against a dispose call removing elements from the Cache. const values = this._values; this._values = new Map(); @@ -107,13 +107,21 @@ export class Cache { } } - dispose(): void { + dispose() { this.clear(); this._entriesSubject.complete(); - } -} + }}exports.Cache = Cache; + // Useful for optional second parameter to Cache constructor. -export const DISPOSE_VALUE = (value: IDisposable) => { - value.dispose(); -}; +/** + * 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. + * + * + * @format + */const DISPOSE_VALUE = exports.DISPOSE_VALUE = value => {value.dispose();}; \ No newline at end of file diff --git a/modules/nuclide-commons/collection.js b/modules/nuclide-commons/collection.js index f341ef7a..804d3241 100644 --- a/modules/nuclide-commons/collection.js +++ b/modules/nuclide-commons/collection.js @@ -1,623 +1,653 @@ -/** - * 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 - * @format - */ - -export function ensureArray(x: Array | T): Array { - return Array.isArray(x) ? x : [x]; -} - -export function arrayRemove(array: Array, element: T): void { - const index = array.indexOf(element); - if (index >= 0) { - array.splice(index, 1); - } -} - -export function arrayEqual( - array1: Array, - array2: Array, - equalComparator?: (a: T, b: T) => boolean, -): boolean { - if (array1 === array2) { - return true; - } - if (array1.length !== array2.length) { - return false; - } - const equalFunction = equalComparator || ((a: T, b: T) => a === b); - return array1.every((item1, i) => equalFunction(item1, array2[i])); -} - -/** - * Returns a copy of the input Array with all `null` and `undefined` values filtered out. - * Allows Flow to typecheck the common `filter(x => x != null)` pattern. - */ -export function arrayCompact(array: Array): Array { - const result = []; - for (const elem of array) { - if (elem != null) { - result.push(elem); - } - } - return result; -} - -/** - * Flattens an Array> into just an Array - */ -export function arrayFlatten(array: Array>): Array { - const result = []; - for (const subArray of array) { - result.push(...subArray); - } - return result; -} - -/** - * Removes duplicates from Array. - * Uses SameValueZero for equality purposes, which is like '===' except it deems - * two NaNs equal. http://www.ecma-international.org/ecma-262/6.0/#sec-samevaluezero - */ -export function arrayUnique(array: Array): Array { - return Array.from(new Set(array)); -} - -/** - * Returns the last index in the input array that matches the predicate. - * Returns -1 if no match is found. - */ -export function arrayFindLastIndex( - array: Array, - predicate: (elem: T, index: number, array: Array) => boolean, - thisArg?: any, -): number { - for (let i = array.length - 1; i >= 0; i--) { - if (predicate.call(thisArg, array[i], i, array)) { - return i; - } - } - return -1; -} - -/** - * Merges a given arguments of maps into one Map, with the latest maps - * overriding the values of the prior maps. - */ -export function mapUnion(...maps: Array>): Map { - const unionMap = new Map(); - for (const map of maps) { - for (const [key, value] of map) { - unionMap.set(key, value); - } - } - return unionMap; -} - -export function mapCompact(map: Map): Map { - const selected = new Map(); - for (const [key, value] of map) { - if (value != null) { - selected.set(key, value); - } - } - return selected; -} - -export function mapFilter( - map: Map, - selector: (key: T, value: X) => boolean, -): Map { - const selected = new Map(); - for (const [key, value] of map) { - if (selector(key, value)) { - selected.set(key, value); - } - } - return selected; -} - -export function mapTransform( - src: Map, - transform: (value: V1, key: T) => V2, -): Map { - const result = new Map(); - for (const [key, value] of src) { - result.set(key, transform(value, key)); - } - return result; -} - -export function mapEqual( - map1: Map, - map2: Map, - equalComparator?: (val1: X, val2: X, key1?: T, key2?: T) => boolean, -) { - if (map1.size !== map2.size) { - return false; - } - const equalFunction = equalComparator || ((a: X, b: X) => a === b); - for (const [key1, value1] of map1) { - if (!map2.has(key1) || !equalFunction(value1, (map2.get(key1): any))) { - return false; - } - } - return true; -} - -export function mapGetWithDefault( - map: Map, - key: K, - default_: V, -): V { - if (map.has(key)) { - // Cast through `any` since map.get's return is a maybe type. We can't just get the value and +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + +ensureArray = ensureArray;exports. + + + +arrayRemove = arrayRemove;exports. + + + + + + +arrayEqual = arrayEqual;exports. + + + + + + + + + + + + + + + + + + +arrayCompact = arrayCompact;exports. + + + + + + + + + + + + +arrayFlatten = arrayFlatten;exports. + + + + + + + + + + + + +arrayUnique = arrayUnique;exports. + + + + + + + +arrayFindLastIndex = arrayFindLastIndex;exports. + + + + + + + + + + + + + + + + +mapUnion = mapUnion;exports. + + + + + + + + + +mapCompact = mapCompact;exports. + + + + + + + + + +mapFilter = mapFilter;exports. + + + + + + + + + + + + +mapTransform = mapTransform;exports. + + + + + + + + + + +mapEqual = mapEqual;exports. + + + + + + + + + + + + + + + + +mapGetWithDefault = mapGetWithDefault;exports. + + + + + + + + + + + + + + +areSetsEqual = areSetsEqual;exports. + + + + +every = every;exports. + + + + + + + + + + + +setIntersect = setIntersect;exports. + + + + + + + + + + + + + +setUnion = setUnion;exports. + + + + + + + + + + + +setDifference = setDifference;exports. + + + + + + + + + + + + + + + + + + + + +setFilter = setFilter;exports. + + + + + + + + + + + + + + + + +isEmpty = isEmpty;exports. + + + + + + + + + + + + +keyMirror = keyMirror;exports. + + + + + + + + + + + +collect = collect;exports. + + + + + + + + + + + + + +objectFromPairs = objectFromPairs;exports. + + + + + + + + + +objectMapValues = objectMapValues;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +objectValues = objectValues;exports. + + + +objectEntries = objectEntries;exports. + + + + + + + + + + + + + + + +objectFromMap = objectFromMap;exports. + + + + + + + +concatIterators = concatIterators;exports. + + + + + + + + + +someOfIterable = someOfIterable;exports. + + + + + + + + + + + +findInIterable = findInIterable;exports. + + + + + + + + + + + +filterIterable = filterIterable;exports. + + + + + + + + + + +mapIterable = mapIterable;exports. + + + + + + + + +takeIterable = takeIterable;exports. + + + + + + + + + + + + + +range = range;exports. + + + + + + + + + +firstOfIterable = firstOfIterable;exports. + + + +iterableIsEmpty = iterableIsEmpty;exports. + + + + + + + +iterableContains = iterableContains;exports. + + + + + +count = count;exports. + + + + + + + + +isIterable = isIterable;exports. + + + + +insideOut = insideOut;exports. + + + + + + + + + + + + + + + + + + + + + + + + + +mapFromObject = mapFromObject;exports. + + + +lastFromArray = lastFromArray;exports. + + + +distinct = distinct; /** + * 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. + * + * + * @format + */function ensureArray(x) {return Array.isArray(x) ? x : [x];}function arrayRemove(array, element) {const index = array.indexOf(element);if (index >= 0) {array.splice(index, 1);}}function arrayEqual(array1, array2, equalComparator) {if (array1 === array2) {return true;}if (array1.length !== array2.length) {return false;}const equalFunction = equalComparator || ((a, b) => a === b);return array1.every((item1, i) => equalFunction(item1, array2[i]));} /** + * Returns a copy of the input Array with all `null` and `undefined` values filtered out. + * Allows Flow to typecheck the common `filter(x => x != null)` pattern. + */function arrayCompact(array) {const result = [];for (const elem of array) {if (elem != null) {result.push(elem);}}return result;} /** + * Flattens an Array> into just an Array + */function arrayFlatten(array) {const result = [];for (const subArray of array) {result.push(...subArray);}return result;} /** + * Removes duplicates from Array. + * Uses SameValueZero for equality purposes, which is like '===' except it deems + * two NaNs equal. http://www.ecma-international.org/ecma-262/6.0/#sec-samevaluezero + */function arrayUnique(array) {return Array.from(new Set(array));} /** + * Returns the last index in the input array that matches the predicate. + * Returns -1 if no match is found. + */function arrayFindLastIndex(array, predicate, thisArg) {for (let i = array.length - 1; i >= 0; i--) {if (predicate.call(thisArg, array[i], i, array)) {return i;}}return -1;} /** + * Merges a given arguments of maps into one Map, with the latest maps + * overriding the values of the prior maps. + */function mapUnion(...maps) {const unionMap = new Map();for (const map of maps) {for (const [key, value] of map) {unionMap.set(key, value);}}return unionMap;}function mapCompact(map) {const selected = new Map();for (const [key, value] of map) {if (value != null) {selected.set(key, value);}}return selected;}function mapFilter(map, selector) {const selected = new Map();for (const [key, value] of map) {if (selector(key, value)) {selected.set(key, value);}}return selected;}function mapTransform(src, transform) {const result = new Map();for (const [key, value] of src) {result.set(key, transform(value, key));}return result;}function mapEqual(map1, map2, equalComparator) {if (map1.size !== map2.size) {return false;}const equalFunction = equalComparator || ((a, b) => a === b);for (const [key1, value1] of map1) {if (!map2.has(key1) || !equalFunction(value1, map2.get(key1))) {return false;}}return true;}function mapGetWithDefault(map, key, default_) {if (map.has(key)) {// Cast through `any` since map.get's return is a maybe type. We can't just get the value and // check it against `null`, since null/undefined may inhabit V. We know this is safe since we // just checked that the map has the key. - return (map.get(key): any); - } else { - return default_; - } -} - -export function areSetsEqual(a: Set, b: Set): boolean { - return a.size === b.size && every(a, element => b.has(element)); -} - -// Array.every but for any iterable. -export function every( - values: Iterable, - predicate: (element: T) => boolean, -): boolean { - for (const element of values) { - if (!predicate(element)) { - return false; - } - } - return true; -} - -export function setIntersect(a: Set, b: Set): Set { - return setFilter(a, e => b.has(e)); -} - -function setUnionTwo(a: Set, b: Set): Set { - // Avoids the extra Array allocations that `new Set([...a, ...b])` would incur. Some quick tests + return map.get(key);} else {return default_;}}function areSetsEqual(a, b) {return a.size === b.size && every(a, element => b.has(element));} // Array.every but for any iterable. +function every(values, predicate) {for (const element of values) {if (!predicate(element)) {return false;}}return true;}function setIntersect(a, b) {return setFilter(a, e => b.has(e));}function setUnionTwo(a, b) {// Avoids the extra Array allocations that `new Set([...a, ...b])` would incur. Some quick tests // indicate it would be about 60% slower. - const result = new Set(a); - b.forEach(x => { - result.add(x); - }); - return result; -} - -export function setUnion(...sets: Array>): Set { - if (sets.length < 1) { - return new Set(); - } - - const setReducer = (accumulator: Set, current: Set): Set => { - return setUnionTwo(accumulator, current); - }; - - return sets.reduce(setReducer); -} - -export function setDifference( - a: Set, - b: Set, - hash_?: (v: T) => any, -): Set { - if (a.size === 0) { - return new Set(); - } else if (b.size === 0) { - return new Set(a); - } - const result = new Set(); - const hash = hash_ || (x => x); - const bHashes = hash_ == null ? b : new Set(Array.from(b.values()).map(hash)); - a.forEach(value => { - if (!bHashes.has(hash(value))) { - result.add(value); - } - }); - return result; -} - -export function setFilter( - set: Set, - predicate: (value: T) => boolean, -): Set { - const out = new Set(); - for (const item of set) { - if (predicate(item)) { - out.add(item); - } - } - - return out; -} - -/** - * O(1)-check if a given object is empty (has no properties, inherited or not) - */ -export function isEmpty(obj: Object): boolean { - for (const key in obj) { - return false; - } - return true; -} - -/** - * Constructs an enumeration with keys equal to their value. - * e.g. keyMirror({a: null, b: null}) => {a: 'a', b: 'b'} - * - * Based off the equivalent function in www. - */ -export function keyMirror(obj: T): {[key: $Enum]: $Enum} { - const ret = {}; - Object.keys(obj).forEach(key => { - ret[key] = key; - }); - return ret; -} - -/** - * Given an array of [key, value] pairs, construct a map where the values for - * each key are collected into an array of values, in order. - */ -export function collect(pairs: Array<[K, V]>): Map> { - const result = new Map(); - for (const pair of pairs) { - const [k, v] = pair; - let list = result.get(k); - if (list == null) { - list = []; - result.set(k, list); - } - list.push(v); - } - return result; -} - -export function objectFromPairs( - iterable: Iterable<[T, U]>, -): {[T]: U} { - const result = {}; - for (const [key, value] of iterable) { - result[key] = value; - } - return result; -} - -export function objectMapValues( - object: {[T: string]: U}, - project: (value: U, key: T) => V, -): {[T]: V} { - const result = {}; - Object.keys(object).forEach(key => { - result[key] = project(object[key], ((key: any): T)); - }); - return result; -} - -export class MultiMap { - // Invariant: no empty sets. They should be removed instead. - _map: Map>; - - // TODO may be worth defining a getter but no setter, to mimic Map. But please just behave and + const result = new Set(a);b.forEach(x => {result.add(x);});return result;}function setUnion(...sets) {if (sets.length < 1) {return new Set();}const setReducer = (accumulator, current) => {return setUnionTwo(accumulator, current);};return sets.reduce(setReducer);}function setDifference(a, b, hash_) {if (a.size === 0) {return new Set();} else if (b.size === 0) {return new Set(a);}const result = new Set();const hash = hash_ || (x => x);const bHashes = hash_ == null ? b : new Set(Array.from(b.values()).map(hash));a.forEach(value => {if (!bHashes.has(hash(value))) {result.add(value);}});return result;}function setFilter(set, predicate) {const out = new Set();for (const item of set) {if (predicate(item)) {out.add(item);}}return out;} /** + * O(1)-check if a given object is empty (has no properties, inherited or not) + */function isEmpty(obj) {for (const key in obj) {return false;}return true;} /** + * Constructs an enumeration with keys equal to their value. + * e.g. keyMirror({a: null, b: null}) => {a: 'a', b: 'b'} + * + * Based off the equivalent function in www. + */function keyMirror(obj) {const ret = {};Object.keys(obj).forEach(key => {ret[key] = key;});return ret;} /** + * Given an array of [key, value] pairs, construct a map where the values for + * each key are collected into an array of values, in order. + */function collect(pairs) {const result = new Map();for (const pair of pairs) {const [k, v] = pair;let list = result.get(k);if (list == null) {list = [];result.set(k, list);}list.push(v);}return result;}function objectFromPairs(iterable) {const result = {};for (const [key, value] of iterable) {result[key] = value;}return result;}function objectMapValues(object, project) {const result = {};Object.keys(object).forEach(key => {result[key] = project(object[key], key);});return result;}class MultiMap {// Invariant: no empty sets. They should be removed instead. + constructor() {this._map = new Map();this.size = 0;} /* + * Returns the set of values associated with the given key. Do not mutate the given set. Copy it + * if you need to store it past the next operation on this MultiMap. + */ // TODO may be worth defining a getter but no setter, to mimic Map. But please just behave and // don't mutate this from outside this class. // // Invariant: equal to the sum of the sizes of all the sets contained in this._map - /* The total number of key-value bindings contained */ - size: number; - - constructor() { - this._map = new Map(); - this.size = 0; - } - - /* - * Returns the set of values associated with the given key. Do not mutate the given set. Copy it - * if you need to store it past the next operation on this MultiMap. - */ - get(key: K): Set { - const set = this._map.get(key); - if (set == null) { - return new Set(); - } - return set; - } - - /* - * Mimics the Map.prototype.set interface. Deliberately did not choose "set" as the name since the - * implication is that it removes the previous binding. - */ - add(key: K, value: V): MultiMap { - let set = this._map.get(key); - if (set == null) { - set = new Set(); - this._map.set(key, set); - } - if (!set.has(value)) { - set.add(value); - this.size++; - } - return this; - } - - /* - * Mimics the Map.prototype.set interface. Replaces the previous binding with new values. - */ - set(key: K, values: Iterable): void { - this.deleteAll(key); - const newSet = new Set(values); - if (newSet.size !== 0) { - this._map.set(key, newSet); - this.size += newSet.size; - } - } - - /* - * Deletes a single binding. Returns true iff the binding existed. - */ - delete(key: K, value: V): boolean { - const set = this.get(key); - const didRemove = set.delete(value); - if (set.size === 0) { - this._map.delete(key); - } - if (didRemove) { - this.size--; - } - return didRemove; - } - - /* - * Deletes all bindings associated with the given key. Returns true iff any bindings were deleted. - */ - deleteAll(key: K): boolean { - const set = this.get(key); - this.size -= set.size; - return this._map.delete(key); - } - - clear(): void { - this._map.clear(); - this.size = 0; - } - - has(key: K, value: V): boolean { - return this.get(key).has(value); - } - - hasAny(key: K): boolean { - return this._map.has(key); - } - - *values(): Iterable { - for (const set of this._map.values()) { - yield* set; - } - } - - forEach(callback: (value: V, key: K, obj: MultiMap) => void): void { - this._map.forEach((values, key) => - values.forEach(value => callback(value, key, this)), - ); - } -} - -export function objectValues(obj: {[key: string]: T}): Array { - return Object.keys(obj).map(key => obj[key]); -} - -export function objectEntries(obj: ?{[key: string]: T}): Array<[string, T]> { - if (obj == null) { - throw new TypeError(); - } - const entries = []; - for (const key in obj) { - if ( - obj.hasOwnProperty(key) && - Object.prototype.propertyIsEnumerable.call(obj, key) - ) { - entries.push([key, obj[key]]); - } - } - return entries; -} - -export function objectFromMap(map: Map): {[key: string]: T} { - const obj = {}; - map.forEach((v, k) => { - obj[k] = v; - }); - return obj; -} - -export function* concatIterators( - ...iterators: Array> -): Iterator { - for (const iterator of iterators) { - for (const element of iterator) { - yield element; - } - } -} - -export function someOfIterable( - iterable: Iterable, - predicate: (element: T) => boolean, -): boolean { - for (const element of iterable) { - if (predicate(element)) { - return true; - } - } - return false; -} - -export function findInIterable( - iterable: Iterable, - predicate: (element: T) => boolean, -): ?T { - for (const element of iterable) { - if (predicate(element)) { - return element; - } - } - return null; -} - -export function* filterIterable( - iterable: Iterable, - predicate: (element: T) => boolean, -): Iterable { - for (const element of iterable) { - if (predicate(element)) { - yield element; - } - } -} - -export function* mapIterable( - iterable: Iterable, - projectorFn: (element: T) => M, -): Iterable { - for (const element of iterable) { - yield projectorFn(element); - } -} - -export function* takeIterable( - iterable: Iterable, - limit: number, -): Iterable { - let i = 0; - for (const element of iterable) { - if (++i > limit) { - break; - } - yield element; - } -} - -// Return an iterable of the numbers start (inclusive) through stop (exclusive) -export function* range( - start: number, - stop: number, - step?: number = 1, -): Iterable { - for (let i = start; i < stop; i += step) { - yield i; - } -} - -export function firstOfIterable(iterable: Iterable): ?T { - return findInIterable(iterable, () => true); -} - -export function iterableIsEmpty(iterable: Iterable): boolean { - // eslint-disable-next-line no-unused-vars - for (const element of iterable) { - return false; - } - return true; -} - -export function iterableContains(iterable: Iterable, value: T): boolean { - return !iterableIsEmpty( - filterIterable(iterable, element => element === value), - ); -} - -export function count(iterable: Iterable): number { - let size = 0; - // eslint-disable-next-line no-unused-vars - for (const element of iterable) { - size++; - } - return size; -} - -export function isIterable(obj: any): boolean { - return typeof obj[Symbol.iterator] === 'function'; -} - -// Traverse an array from the inside out, starting at the specified index. -export function* insideOut( - arr: Array, - startingIndex?: number, -): Iterable<[T, number]> { - if (arr.length === 0) { - return; - } - - let i = - startingIndex == null - ? Math.floor(arr.length / 2) - : Math.min(arr.length, Math.max(0, startingIndex)); - let j = i - 1; - - while (i < arr.length || j >= 0) { - if (i < arr.length) { - yield [arr[i], i]; - i++; - } - if (j >= 0) { - yield [arr[j], j]; - j--; - } - } -} - -export function mapFromObject(obj: {[key: string]: T}): Map { - return new Map(objectEntries(obj)); -} - -export function lastFromArray(arr: Array): T { - return arr[arr.length - 1]; -} - -export function distinct(array: T[], keyFn?: (t: T) => string): T[] { - if (keyFn == null) { - return Array.from(new Set(array)); - } - - const seenKeys = new Set(); - return array.filter(elem => { - const key = keyFn(elem); - if (seenKeys.has(key)) { - return false; - } - seenKeys.add(key); - return true; - }); -} - -export class DefaultMap extends Map { - _factory: () => V; - - constructor(factory: () => V, iterable: ?Iterable<[K, V]>) { - super(iterable); - this._factory = factory; - } - - get(key: K): V { - if (!this.has(key)) { - const value = this._factory(); - this.set(key, value); - return value; - } - // If the key is present we must have a value of type V. - return (super.get(key): any); - } -} + /* The total number of key-value bindings contained */get(key) {const set = this._map.get(key);if (set == null) {return new Set();}return set;} /* + * Mimics the Map.prototype.set interface. Deliberately did not choose "set" as the name since the + * implication is that it removes the previous binding. + */add(key, value) {let set = this._map.get(key);if (set == null) {set = new Set();this._map.set(key, set);}if (!set.has(value)) {set.add(value);this.size++;}return this;} /* + * Mimics the Map.prototype.set interface. Replaces the previous binding with new values. + */set(key, values) {this.deleteAll(key);const newSet = new Set(values);if (newSet.size !== 0) {this._map.set(key, newSet);this.size += newSet.size;}} /* + * Deletes a single binding. Returns true iff the binding existed. + */delete(key, value) {const set = this.get(key);const didRemove = set.delete(value);if (set.size === 0) {this._map.delete(key);}if (didRemove) {this.size--;}return didRemove;} /* + * Deletes all bindings associated with the given key. Returns true iff any bindings were deleted. + */deleteAll(key) {const set = this.get(key);this.size -= set.size;return this._map.delete(key);}clear() {this._map.clear();this.size = 0;}has(key, value) {return this.get(key).has(value);}hasAny(key) {return this._map.has(key);}*values() {for (const set of this._map.values()) {yield* set;}}forEach(callback) {this._map.forEach((values, key) => values.forEach(value => callback(value, key, this)));}}exports.MultiMap = MultiMap;function objectValues(obj) {return Object.keys(obj).map(key => obj[key]);}function objectEntries(obj) {if (obj == null) {throw new TypeError();}const entries = [];for (const key in obj) {if (obj.hasOwnProperty(key) && Object.prototype.propertyIsEnumerable.call(obj, key)) {entries.push([key, obj[key]]);}}return entries;}function objectFromMap(map) {const obj = {};map.forEach((v, k) => {obj[k] = v;});return obj;}function* concatIterators(...iterators) {for (const iterator of iterators) {for (const element of iterator) {yield element;}}}function someOfIterable(iterable, predicate) {for (const element of iterable) {if (predicate(element)) {return true;}}return false;}function findInIterable(iterable, predicate) {for (const element of iterable) {if (predicate(element)) {return element;}}return null;}function* filterIterable(iterable, predicate) {for (const element of iterable) {if (predicate(element)) {yield element;}}}function* mapIterable(iterable, projectorFn) {for (const element of iterable) {yield projectorFn(element);}}function* takeIterable(iterable, limit) {let i = 0;for (const element of iterable) {if (++i > limit) {break;}yield element;}} // Return an iterable of the numbers start (inclusive) through stop (exclusive) +function* range(start, stop, step = 1) {for (let i = start; i < stop; i += step) {yield i;}}function firstOfIterable(iterable) {return findInIterable(iterable, () => true);}function iterableIsEmpty(iterable) {// eslint-disable-next-line no-unused-vars + for (const element of iterable) {return false;}return true;}function iterableContains(iterable, value) {return !iterableIsEmpty(filterIterable(iterable, element => element === value));}function count(iterable) {let size = 0; // eslint-disable-next-line no-unused-vars + for (const element of iterable) {size++;}return size;}function isIterable(obj) {return typeof obj[Symbol.iterator] === 'function';} // Traverse an array from the inside out, starting at the specified index. +function* insideOut(arr, startingIndex) {if (arr.length === 0) {return;}let i = startingIndex == null ? Math.floor(arr.length / 2) : Math.min(arr.length, Math.max(0, startingIndex));let j = i - 1;while (i < arr.length || j >= 0) {if (i < arr.length) {yield [arr[i], i];i++;}if (j >= 0) {yield [arr[j], j];j--;}}}function mapFromObject(obj) {return new Map(objectEntries(obj));}function lastFromArray(arr) {return arr[arr.length - 1];}function distinct(array, keyFn) {if (keyFn == null) {return Array.from(new Set(array));}const seenKeys = new Set();return array.filter(elem => {const key = keyFn(elem);if (seenKeys.has(key)) {return false;}seenKeys.add(key);return true;});}class DefaultMap extends Map {constructor(factory, iterable) {super(iterable);this._factory = factory;}get(key) {if (!this.has(key)) {const value = this._factory();this.set(key, value);return value;} // If the key is present we must have a value of type V. + return super.get(key);}}exports.DefaultMap = DefaultMap; \ No newline at end of file diff --git a/modules/nuclide-commons/debounce.js b/modules/nuclide-commons/debounce.js index 54c6172a..8a5eb26c 100644 --- a/modules/nuclide-commons/debounce.js +++ b/modules/nuclide-commons/debounce.js @@ -1,46 +1,46 @@ -/** - * 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 - * @format - */ - -import invariant from 'assert'; - -export default function debounce< - T, - TArgs: Array, - TReturn, - TFunc: (...TArgs) => TReturn, // eslint-disable-line space-before-function-paren ->( - func: TFunc, - wait: number, - immediate?: boolean = false, -): { - (...TArgs): TReturn | void, - dispose(): void, -} { +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default = + + + + + + + + + + + + + +debounce;function debounce( + + + + + +func, +wait, +immediate = false) + + + +{ // Taken from: https://github.com/jashkenas/underscore/blob/b10b2e6d72/underscore.js#L815. - let timeout: ?TimeoutID; - let args: ?TArgs; - let context: any; + let timeout; + let args; + let context; let timestamp = 0; - let result: TReturn | void; + let result; - const later = function() { + const later = function () { const last = Date.now() - timestamp; if (last < wait && last >= 0) { timeout = setTimeout(later, wait - last); } else { timeout = null; - if (!immediate) { - invariant(args != null); + if (!immediate) {if (!( + args != null)) {throw new Error('Invariant violation: "args != null"');} result = func.apply(context, args); if (!timeout) { context = args = null; @@ -49,7 +49,7 @@ export default function debounce< } }; - const debounced = function(...args_: TArgs): TReturn | void { + const debounced = function (...args_) { context = this; args = args_; timestamp = Date.now(); @@ -73,4 +73,14 @@ export default function debounce< }; return debounced; -} +} /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/event.js b/modules/nuclide-commons/event.js index 085e1032..8eeb206e 100644 --- a/modules/nuclide-commons/event.js +++ b/modules/nuclide-commons/event.js @@ -1,44 +1,49 @@ -/** - * 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 - * @format - */ - -import UniversalDisposable from './UniversalDisposable'; -import {Observable} from 'rxjs'; - -/** - * Add an event listener an return a disposable for removing it. Note that this function assumes - * node EventEmitter semantics: namely, that adding the same combination of eventName and callback - * adds a second listener. - */ -export function attachEvent( - emitter: events$EventEmitter, - eventName: string, - callback: Function, -): IDisposable { - emitter.addListener(eventName, callback); - return new UniversalDisposable(() => { - emitter.removeListener(eventName, callback); - }); -} - -type SubscribeCallback = (item: T) => any; -type SubscribeFunction = (callback: SubscribeCallback) => IDisposable; - -export function observableFromSubscribeFunction( - fn: SubscribeFunction, -): Observable { - return Observable.create(observer => { - const disposable = fn(observer.next.bind(observer)); - return () => { - disposable.dispose(); - }; - }); -} +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + + + + + + + +attachEvent = attachEvent;exports. + + + + + + + + + + + + + +observableFromSubscribeFunction = observableFromSubscribeFunction;var _UniversalDisposable;function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('./UniversalDisposable'));}var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * Add an event listener an return a disposable for removing it. Note that this function assumes + * node EventEmitter semantics: namely, that adding the same combination of eventName and callback + * adds a second listener. + */ /** + * 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. + * + * + * @format + */function attachEvent(emitter, eventName, callback) {emitter.addListener(eventName, callback);return new (_UniversalDisposable || _load_UniversalDisposable()).default(() => {emitter.removeListener(eventName, callback);});}function observableFromSubscribeFunction(fn) {return _rxjsBundlesRxMinJs.Observable.create(observer => {const disposable = fn(observer.next.bind(observer));return () => {disposable.dispose();};});} \ No newline at end of file diff --git a/modules/nuclide-commons/expected.js b/modules/nuclide-commons/expected.js index 0b3276ae..1cb9d67e 100644 --- a/modules/nuclide-commons/expected.js +++ b/modules/nuclide-commons/expected.js @@ -1,78 +1,77 @@ -/** - * 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 - * @format - */ +"use strict";Object.defineProperty(exports, "__esModule", { value: true }); /** + * 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. + * + * + * @format + */ /** - * Expected tries to mimic llvm's Expected class. - * This is specially useful for Observables that can return a stream of errors instead of closing - * the subscription. - */ - -type ExpectedError = { - isError: true, - isPending: false, - error: Error, - getOrDefault: (def: T) => T, -}; - -type ExpectedValue = { - isError: false, - isPending: false, - value: T, - getOrDefault: (def: T) => T, -}; - -type ExpectedPendingValue = { - isError: false, - isPending: true, - value: T, - getOrDefault: (def: T) => T, -}; - -export type Expected = - | ExpectedError - | ExpectedValue - | ExpectedPendingValue; - -export class Expect { - static error(error: Error): ExpectedError { + * Expected tries to mimic llvm's Expected class. + * This is specially useful for Observables that can return a stream of errors instead of closing + * the subscription. + */ + + + + + + + + + + + + + + + + + + + + + + + + + + + +class Expect { + static error(error) { return { isError: true, isPending: false, error, - getOrDefault(def: T): T { + getOrDefault(def) { return def; - }, - }; + } }; + } - static value(value: T): ExpectedValue { + static value(value) { return { isError: false, isPending: false, value, - getOrDefault(def: T): T { + getOrDefault(def) { return this.value; - }, - }; + } }; + } - static pendingValue(value: T): ExpectedPendingValue { + static pendingValue(value) { return { isError: false, isPending: true, value, - getOrDefault(def: T): T { + getOrDefault(def) { return this.value; - }, - }; - } -} + } }; + + }}exports.Expect = Expect; \ No newline at end of file diff --git a/modules/nuclide-commons/fsPromise.js b/modules/nuclide-commons/fsPromise.js index 212b8987..83879fa2 100644 --- a/modules/nuclide-commons/fsPromise.js +++ b/modules/nuclide-commons/fsPromise.js @@ -1,628 +1,628 @@ +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /** - * 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 - * @format - */ - -import fs from 'fs'; -import fsPlus from 'fs-plus'; -import globLib from 'glob'; -import mkdirpLib from 'mkdirp'; -import mvLib from 'mv'; -import rimraf from 'rimraf'; -import temp from 'temp'; - -import nuclideUri from './nuclideUri'; -import {runCommand} from './process'; + * Searches upward through the filesystem from pathToDirectory to find a file with + * fileName. + * @param fileName The name of the file to find. + * @param pathToDirectory Where to begin the search. Must be a path to a directory, + * not a file. + * @return directory that contains the nearest file or null. + */let findNearestFile = (() => {var _ref = (0, _asyncToGenerator.default)( + function* ( + fileName, + pathToDirectory) + { + // TODO(5586355): If this becomes a bottleneck, we should consider memoizing + // this function. The downside would be that if someone added a closer file + // with fileName to pathToFile (or deleted the one that was cached), then we + // would have a bug. This would probably be pretty rare, though. + let currentPath = (_nuclideUri || _load_nuclideUri()).default.resolve(pathToDirectory); + for (;;) { + const fileToFind = (_nuclideUri || _load_nuclideUri()).default.join(currentPath, fileName); + // eslint-disable-next-line no-await-in-loop + const hasFile = yield exists(fileToFind); + if (hasFile) { + return currentPath; + } + if ((_nuclideUri || _load_nuclideUri()).default.isRoot(currentPath)) { + return null; + } + currentPath = (_nuclideUri || _load_nuclideUri()).default.dirname(currentPath); + } + });return function findNearestFile(_x, _x2) {return _ref.apply(this, arguments);};})(); + +/** + * Searches upward through the filesystem from pathToDirectory to find the furthest + * file with fileName. + * @param fileName The name of the file to find. + * @param pathToDirectory Where to begin the search. Must be a path to a directory, + * not a file. + * @param stopOnMissing Stop searching when we reach a directory without fileName. + * @return directory that contains the furthest file or null. + */let findFurthestFile = (() => {var _ref2 = (0, _asyncToGenerator.default)( + function* ( + fileName, + pathToDirectory, + stopOnMissing = false) + { + let currentPath = (_nuclideUri || _load_nuclideUri()).default.resolve(pathToDirectory); + let result = null; + for (;;) { + const fileToFind = (_nuclideUri || _load_nuclideUri()).default.join(currentPath, fileName); + // eslint-disable-next-line no-await-in-loop + const hasFile = yield exists(fileToFind); + if (!hasFile && stopOnMissing || (_nuclideUri || _load_nuclideUri()).default.isRoot(currentPath)) { + return result; + } else if (hasFile) { + result = currentPath; + } + currentPath = (_nuclideUri || _load_nuclideUri()).default.dirname(currentPath); + } + });return function findFurthestFile(_x3, _x4) {return _ref2.apply(this, arguments);};})(); + + + + + + + + + + + + + + + + + +/** + * Runs the equivalent of `mkdir -p` with the given path. + * + * Like most implementations of mkdirp, if it fails, it is possible that + * directories were created for some prefix of the given path. + * @return true if the path was created; false if it already existed. + */let mkdirp = (() => {var _ref3 = (0, _asyncToGenerator.default)( + function* (filePath) { + const isExistingDirectory = yield exists(filePath); + if (isExistingDirectory) { + return false; + } else { + return new Promise(function (resolve, reject) { + (0, (_mkdirp || _load_mkdirp()).default)(filePath, function (err) { + if (err) { + reject(err); + } else { + resolve(true); + } + }); + }); + } + });return function mkdirp(_x5) {return _ref3.apply(this, arguments);};})(); + +/** + * Removes directories even if they are non-empty. Does not fail if the directory doesn't exist. + */let getFileSystemType = (() => {var _ref4 = (0, _asyncToGenerator.default)( + + + + + + + + + + + + + function* (entityPath) { + if (process.platform === 'linux' || process.platform === 'darwin') { + try { + const stdout = yield (0, (_process || _load_process()).runCommand)('stat', [ + '-f', + '-L', + '-c', + '%T', + entityPath]). + toPromise(); + return stdout.trim(); + } catch (err) { + return null; + } + } else { + // TODO Handle other platforms (windows?) + return null; + } + });return function getFileSystemType(_x6) {return _ref4.apply(this, arguments);};})(); + +/** @return true only if we are sure entityPath is on NFS. */let isNfs = (() => {var _ref5 = (0, _asyncToGenerator.default)( + function* (entityPath) { + return (yield getFileSystemType(entityPath)) === 'nfs'; + });return function isNfs(_x7) {return _ref5.apply(this, arguments);};})(); + +/** @return true only if we are sure entityPath is on a Fuse filesystem like + dewey or gvfs. + */let isFuse = (() => {var _ref6 = (0, _asyncToGenerator.default)( + function* (entityPath) { + return (yield getFileSystemType(entityPath)) === 'fuseblk'; + });return function isFuse(_x8) {return _ref6.apply(this, arguments);};})();let isNonNfsDirectory = (() => {var _ref7 = (0, _asyncToGenerator.default)( + + + + + + + + + + + + + + function* (directoryPath) { + try { + const stats = yield stat(directoryPath); + if (stats.isDirectory()) { + return !(yield isNfs(directoryPath)); + } else { + return false; + } + } catch (e) { + // If the directory cannot be probed for whatever reason, just + // indicate that this is not a valid candidate directory. + // Typically this is ENOENT for missing directory. + return false; + } + });return function isNonNfsDirectory(_x9) {return _ref7.apply(this, arguments);};})(); + +/** + * Promisified wrappers around fs-plus functions. + */let copyFilePermissions = (() => {var _ref8 = (0, _asyncToGenerator.default)( + + + + + + + + + + + + + + function* ( + sourcePath, + destinationPath) + { + try { + const { mode, uid, gid } = yield stat(sourcePath); + yield Promise.all([ + // The user may not have permissions to use the uid/gid. + chown(destinationPath, uid, gid).catch(function () {}), + chmod(destinationPath, mode)]); + + } catch (e) { + // If the file does not exist, then ENOENT will be thrown. + if (e.code !== 'ENOENT') { + throw e; + } + // For new files, use the default process file creation mask. + yield chmod( + destinationPath, + 0o666 & ~process.umask() // eslint-disable-line no-bitwise + ); + } + });return function copyFilePermissions(_x10, _x11) {return _ref8.apply(this, arguments);};})(); + +/** + * TODO: the fs-plus `writeFile` implementation runs `mkdirp` first. + * We should use `fs.writeFile` and have callsites explicitly opt-in to this behaviour. + */let writeFileAtomic = (() => {var _ref9 = (0, _asyncToGenerator.default)( + + + + + + + + + + + + + + + + + function* ( + path, + data, + options) + { + const tempFilePath = yield tempfile('nuclide'); + try { + yield writeFile(tempFilePath, data, options); + + // Expand the target path in case it contains symlinks. + let realPath = path; + try { + realPath = yield realpath(path); + } catch (e) { + + + + } // Fallback to using the specified path if it cannot be expanded. + // Note: this is expected in cases where the remote file does not + // actually exist. + // Ensure file still has original permissions: + // https://github.com/facebook/nuclide/issues/157 + // We update the mode of the temp file rather than the destination file because + // if we did the mv() then the chmod(), there would be a brief period between + // those two operations where the destination file might have the wrong permissions. + yield copyFilePermissions(realPath, tempFilePath); + // TODO: put renames into a queue so we don't write older save over new save. + // Use mv as fs.rename doesn't work across partitions. + yield mv(tempFilePath, realPath, { mkdirp: true }); + } catch (err) { + yield unlink(tempFilePath); + throw err; + } + });return function writeFileAtomic(_x12, _x13, _x14) {return _ref9.apply(this, arguments);};})(); + +/** + * Promisified wrappers around fs functions. + */ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -/** - * Create a temp directory with given prefix. The caller is responsible for cleaning up the - * drectory. - * @param prefix optinal prefix for the temp directory name. - * @return path to a temporary directory. - */ -function tempdir(prefix: string = ''): Promise { - return new Promise((resolve, reject) => { - temp.mkdir(prefix, (err, result) => { - if (err == null) { - resolve(result); - } else { - reject(err); - } - }); - }); -} -/** - * @return path to a temporary file. The caller is responsible for cleaning up - * the file. - */ -function tempfile(options: any): Promise { - return new Promise((resolve, reject) => { - temp.open(options, (err, info) => { - if (err) { - reject(err); - } else { - fs.close(info.fd, closeErr => { - if (closeErr) { - reject(closeErr); - } else { - resolve(info.path); - } - }); - } - }); - }); -} -/** - * Searches upward through the filesystem from pathToDirectory to find a file with - * fileName. - * @param fileName The name of the file to find. - * @param pathToDirectory Where to begin the search. Must be a path to a directory, - * not a file. - * @return directory that contains the nearest file or null. - */ -async function findNearestFile( - fileName: string, - pathToDirectory: string, -): Promise { - // TODO(5586355): If this becomes a bottleneck, we should consider memoizing - // this function. The downside would be that if someone added a closer file - // with fileName to pathToFile (or deleted the one that was cached), then we - // would have a bug. This would probably be pretty rare, though. - let currentPath = nuclideUri.resolve(pathToDirectory); - for (;;) { - const fileToFind = nuclideUri.join(currentPath, fileName); - // eslint-disable-next-line no-await-in-loop - const hasFile = await exists(fileToFind); - if (hasFile) { - return currentPath; - } - if (nuclideUri.isRoot(currentPath)) { - return null; - } - currentPath = nuclideUri.dirname(currentPath); - } -} -/** - * Searches upward through the filesystem from pathToDirectory to find the furthest - * file with fileName. - * @param fileName The name of the file to find. - * @param pathToDirectory Where to begin the search. Must be a path to a directory, - * not a file. - * @param stopOnMissing Stop searching when we reach a directory without fileName. - * @return directory that contains the furthest file or null. - */ -async function findFurthestFile( - fileName: string, - pathToDirectory: string, - stopOnMissing: boolean = false, -): Promise { - let currentPath = nuclideUri.resolve(pathToDirectory); - let result = null; - for (;;) { - const fileToFind = nuclideUri.join(currentPath, fileName); - // eslint-disable-next-line no-await-in-loop - const hasFile = await exists(fileToFind); - if ((!hasFile && stopOnMissing) || nuclideUri.isRoot(currentPath)) { - return result; - } else if (hasFile) { - result = currentPath; - } - currentPath = nuclideUri.dirname(currentPath); - } -} -function getCommonAncestorDirectory(filePaths: Array): string { - let commonDirectoryPath = nuclideUri.dirname(filePaths[0]); - while ( - filePaths.some(filePath => !filePath.startsWith(commonDirectoryPath)) - ) { - commonDirectoryPath = nuclideUri.dirname(commonDirectoryPath); - } - return commonDirectoryPath; -} -function exists(filePath: string): Promise { - return new Promise((resolve, reject) => { - fs.exists(filePath, resolve); - }); -} -/** - * Runs the equivalent of `mkdir -p` with the given path. - * - * Like most implementations of mkdirp, if it fails, it is possible that - * directories were created for some prefix of the given path. - * @return true if the path was created; false if it already existed. - */ -async function mkdirp(filePath: string): Promise { - const isExistingDirectory = await exists(filePath); - if (isExistingDirectory) { - return false; - } else { - return new Promise((resolve, reject) => { - mkdirpLib(filePath, err => { - if (err) { - reject(err); - } else { - resolve(true); - } - }); - }); - } -} -/** - * Removes directories even if they are non-empty. Does not fail if the directory doesn't exist. - */ -function rimrafWrapper(filePath: string): Promise { - return new Promise((resolve, reject) => { - rimraf(filePath, (err, result) => { - if (err == null) { - resolve(result); - } else { - reject(err); - } - }); - }); -} -async function getFileSystemType(entityPath: string): Promise { - if (process.platform === 'linux' || process.platform === 'darwin') { - try { - const stdout = await runCommand('stat', [ - '-f', - '-L', - '-c', - '%T', - entityPath, - ]).toPromise(); - return stdout.trim(); - } catch (err) { - return null; - } - } else { - // TODO Handle other platforms (windows?) - return null; - } -} -/** @return true only if we are sure entityPath is on NFS. */ -async function isNfs(entityPath: string): Promise { - return (await getFileSystemType(entityPath)) === 'nfs'; -} -/** @return true only if we are sure entityPath is on a Fuse filesystem like - dewey or gvfs. -*/ -async function isFuse(entityPath: string): Promise { - return (await getFileSystemType(entityPath)) === 'fuseblk'; -} -function glob(pattern: string, options?: Object): Promise> { - return new Promise((resolve, reject) => { - globLib(pattern, options, (err, result) => { - if (err == null) { - resolve(result); - } else { - reject(err); - } - }); - }); -} -async function isNonNfsDirectory(directoryPath: string): Promise { - try { - const stats = await stat(directoryPath); - if (stats.isDirectory()) { - return !(await isNfs(directoryPath)); - } else { - return false; - } - } catch (e) { - // If the directory cannot be probed for whatever reason, just - // indicate that this is not a valid candidate directory. - // Typically this is ENOENT for missing directory. - return false; - } -} -/** - * Promisified wrappers around fs-plus functions. - */ -function copy(source: string, dest: string): Promise { - return new Promise((resolve, reject) => { - fsPlus.copy(source, dest, (err, result) => { - if (err == null) { - resolve(result); - } else { - reject(err); - } - }); - }); -} -async function copyFilePermissions( - sourcePath: string, - destinationPath: string, -): Promise { - try { - const {mode, uid, gid} = await stat(sourcePath); - await Promise.all([ - // The user may not have permissions to use the uid/gid. - chown(destinationPath, uid, gid).catch(() => {}), - chmod(destinationPath, mode), - ]); - } catch (e) { - // If the file does not exist, then ENOENT will be thrown. - if (e.code !== 'ENOENT') { - throw e; - } - // For new files, use the default process file creation mask. - await chmod( - destinationPath, - 0o666 & ~process.umask(), // eslint-disable-line no-bitwise - ); - } -} -/** - * TODO: the fs-plus `writeFile` implementation runs `mkdirp` first. - * We should use `fs.writeFile` and have callsites explicitly opt-in to this behaviour. - */ -function writeFile( - filename: string, - data: Buffer | string, - options?: Object | string, -): Promise { - return new Promise((resolve, reject) => { - fsPlus.writeFile(filename, data, options, (err, result) => { - if (err == null) { - resolve(result); - } else { - reject(err); - } - }); - }); -} -async function writeFileAtomic( - path: string, - data: Buffer | string, - options?: Object | string, -): Promise { - const tempFilePath = await tempfile('nuclide'); - try { - await writeFile(tempFilePath, data, options); - - // Expand the target path in case it contains symlinks. - let realPath = path; - try { - realPath = await realpath(path); - } catch (e) { - // Fallback to using the specified path if it cannot be expanded. - // Note: this is expected in cases where the remote file does not - // actually exist. - } - // Ensure file still has original permissions: - // https://github.com/facebook/nuclide/issues/157 - // We update the mode of the temp file rather than the destination file because - // if we did the mv() then the chmod(), there would be a brief period between - // those two operations where the destination file might have the wrong permissions. - await copyFilePermissions(realPath, tempFilePath); - - // TODO: put renames into a queue so we don't write older save over new save. - // Use mv as fs.rename doesn't work across partitions. - await mv(tempFilePath, realPath, {mkdirp: true}); - } catch (err) { - await unlink(tempFilePath); - throw err; - } -} -/** - * Promisified wrappers around fs functions. - */ -function chmod(path: string, mode: number | string): Promise { - return new Promise((resolve, reject) => { - fs.chmod(path, mode, (err, result) => { - if (err == null) { - resolve(result); - } else { - reject(err); - } - }); - }); -} -function chown(path: string, uid: number, gid: number): Promise { - return new Promise((resolve, reject) => { - fs.chown(path, uid, gid, (err, result) => { - if (err == null) { - resolve(result); - } else { - reject(err); - } - }); - }); -} -function close(fd: number): Promise { - return new Promise((resolve, reject) => { - fs.close(fd, err => { - if (err == null) { - resolve(); - } else { - reject(err); - } - }); - }); -} -function lstat(path: string): Promise { - return new Promise((resolve, reject) => { - fs.lstat(path, (err, result) => { - if (err == null) { - resolve(result); - } else { - reject(err); - } - }); - }); -} -function mkdir(path: string, mode?: number): Promise { - return new Promise((resolve, reject) => { - fs.mkdir(path, mode, (err, result) => { - if (err == null) { - resolve(result); - } else { - reject(err); - } - }); - }); -} -export type MvOptions = { - // Run mkdirp for the directory first. Defaults to false. - mkdirp?: boolean, - // Overwrite the file if it exists. Defaults to true. - clobber?: boolean, - // Optional: the concurrency limit when moving a directory. - limit?: number, -}; -/** - * The key difference between 'mv' and 'rename' is that 'mv' works across devices. - * It's not uncommon to have temporary files in a different disk, for instance. - */ -function mv( - sourcePath: string, - destinationPath: string, - options?: MvOptions = {}, -): Promise { - return new Promise((resolve, reject) => { - mvLib(sourcePath, destinationPath, options, error => { - if (error) { - reject(error); - } else { - resolve(); - } - }); - }); -} -function open( - path: string | Buffer | URL, - flags: string | number, - mode: number = 0o666, -): Promise { - return new Promise((resolve, reject) => { - fs.open(path, flags, mode, (err, fd) => { - if (err == null) { - resolve(fd); - } else { - reject(err); - } - }); - }); -} -function read( - fd: number, - buffer: Buffer, - offset: number, - length: number, - position: number | null, -): Promise { - return new Promise((resolve, reject) => { - fs.read(fd, buffer, offset, length, position, (err, bytesRead) => { - if (err == null) { - resolve(bytesRead); - } else { - reject(err); - } - }); - }); -} -// `fs.readFile` returns a Buffer unless an encoding is specified. -// This workaround is adapted from the Flow declarations. -type ReadFileType = ((filename: string, encoding: string) => Promise) & - (( - filename: string, - options: {encoding: string, flag?: string}, - ) => Promise) & - ((filename: string, options?: {flag?: string}) => Promise); - -const readFile: ReadFileType = (function(...args: Array) { - return new Promise((resolve, reject) => { - // $FlowIssue: spread operator doesn't preserve any-type - fs.readFile(...args, (err, result) => { - if (err == null) { - resolve(result); - } else { - reject(err); - } - }); - }); -}: any); -function readdir(path: string): Promise> { - return new Promise((resolve, reject) => { - fs.readdir(path, (err, result) => { - if (err == null) { - resolve(result); - } else { - reject(err); - } - }); - }); -} -function readlink(path: string): Promise { - return new Promise((resolve, reject) => { - fs.readlink(path, (err, result) => { - if (err == null) { - resolve(result); - } else { - reject(err); - } - }); - }); -} -function realpath(path: string, cache?: Object): Promise { - return new Promise((resolve, reject) => { - fs.realpath(path, cache, (err, result) => { - if (err == null) { - resolve(result); - } else { - reject(err); - } - }); - }); -} -function access(path: string, mode: number): Promise { - return new Promise((resolve, reject) => { - fs.access(path, mode, err => { - if (err == null) { - resolve(true); - } else { - resolve(false); - } - }); - }); -} -function stat(path: string): Promise { - return new Promise((resolve, reject) => { - fs.stat(path, (err, result) => { - if (err == null) { - resolve(result); - } else { - reject(err); - } - }); - }); -} -function symlink(source: string, dest: string, type?: string): Promise { - return new Promise((resolve, reject) => { - fs.symlink(source, dest, type, (err, result) => { - if (err == null) { - resolve(result); - } else { - reject(err); - } - }); - }); -} /** - * A utility function to grab the last N bytes from a file. Attempts to do so - * without reading the entire file. - */ -async function tailBytes(file: string, maxBytes: number): Promise { - if (maxBytes <= 0) { - throw new Error('tailbytes expects maxBytes > 0'); - } - - // Figure out the size so we know what strategy to use - const {size: file_size} = await stat(file); - - if (file_size > maxBytes) { - const fd = await open(file, 'r'); - const buffer = Buffer.alloc(maxBytes); - const bytesRead = await read( + * A utility function to grab the last N bytes from a file. Attempts to do so + * without reading the entire file. + */let tailBytes = (() => {var _ref10 = (0, _asyncToGenerator.default)( + function* (file, maxBytes) { + if (maxBytes <= 0) { + throw new Error('tailbytes expects maxBytes > 0'); + } + + // Figure out the size so we know what strategy to use + const { size: file_size } = yield stat(file); + + if (file_size > maxBytes) { + const fd = yield open(file, 'r'); + const buffer = Buffer.alloc(maxBytes); + const bytesRead = yield read( fd, buffer, 0, // buffer offset maxBytes, // length to read - file_size - maxBytes, // file offset - ); - await close(fd); - - /* If we meant to read the last 100 bytes but only read 50 bytes, then we've - * failed to read the last 100 bytes. So throw. In the future, someone - * could update this code to keep calling `read` until we read maxBytes. - */ - if (bytesRead !== maxBytes) { - throw new Error( - `Failed to tail file. Intended to read ${maxBytes} bytes but ` + - `only read ${bytesRead} bytes`, + file_size - maxBytes // file offset ); - } - return buffer; - } else { - return readFile(file); - } -} + yield close(fd); + + /* If we meant to read the last 100 bytes but only read 50 bytes, then we've + * failed to read the last 100 bytes. So throw. In the future, someone + * could update this code to keep calling `read` until we read maxBytes. + */ + if (bytesRead !== maxBytes) { + throw new Error( + `Failed to tail file. Intended to read ${maxBytes} bytes but ` + + `only read ${bytesRead} bytes`); -function unlink(path: string): Promise { - return new Promise((resolve, reject) => { - fs.unlink(path, (err, result) => { - if (err == null) { - resolve(result); - } else { - reject(err); } - }); - }); -} - -function utimes( - path: string, - atime: number | Date, - mtime: number | Date, -): Promise { - return new Promise((resolve, reject) => { - fs.utimes(path, atime, mtime, err => { - if (err == null) { - resolve(); - } else { - reject(err); + return buffer; + } else { + return readFile(file); + } + });return function tailBytes(_x15, _x16) {return _ref10.apply(this, arguments);};})();var _fs = _interopRequireDefault(require('fs'));var _fsPlus;function _load_fsPlus() {return _fsPlus = _interopRequireDefault(require('fs-plus'));}var _glob;function _load_glob() {return _glob = _interopRequireDefault(require('glob'));}var _mkdirp;function _load_mkdirp() {return _mkdirp = _interopRequireDefault(require('mkdirp'));}var _mv;function _load_mv() {return _mv = _interopRequireDefault(require('mv'));}var _rimraf;function _load_rimraf() {return _rimraf = _interopRequireDefault(require('rimraf'));}var _temp;function _load_temp() {return _temp = _interopRequireDefault(require('temp'));}var _nuclideUri;function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('./nuclideUri'));}var _process;function _load_process() {return _process = require('./process');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * Create a temp directory with given prefix. The caller is responsible for cleaning up the + * drectory. + * @param prefix optinal prefix for the temp directory name. + * @return path to a temporary directory. + */function tempdir(prefix = '') {return new Promise((resolve, reject) => {(_temp || _load_temp()).default.mkdir(prefix, (err, result) => {if (err == null) {resolve(result);} else {reject(err);}});});} /** + * @return path to a temporary file. The caller is responsible for cleaning up + * the file. + */ /** + * 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. + * + * + * @format + */function tempfile(options) {return new Promise((resolve, reject) => {(_temp || _load_temp()).default.open(options, (err, info) => {if (err) {reject(err);} else {_fs.default.close(info.fd, closeErr => {if (closeErr) {reject(closeErr);} else {resolve(info.path);}});}});});}function getCommonAncestorDirectory(filePaths) {let commonDirectoryPath = (_nuclideUri || _load_nuclideUri()).default.dirname(filePaths[0]);while (filePaths.some(filePath => !filePath.startsWith(commonDirectoryPath))) {commonDirectoryPath = (_nuclideUri || _load_nuclideUri()).default.dirname(commonDirectoryPath);}return commonDirectoryPath;}function exists(filePath) {return new Promise((resolve, reject) => {_fs.default.exists(filePath, resolve);});}function rimrafWrapper(filePath) {return new Promise((resolve, reject) => {(0, (_rimraf || _load_rimraf()).default)(filePath, (err, result) => {if (err == null) {resolve(result);} else {reject(err);}});});}function glob(pattern, options) {return new Promise((resolve, reject) => {(0, (_glob || _load_glob()).default)(pattern, options, (err, result) => {if (err == null) {resolve(result);} else {reject(err);}});});}function copy(source, dest) {return new Promise((resolve, reject) => {(_fsPlus || _load_fsPlus()).default.copy(source, dest, (err, result) => {if (err == null) {resolve(result);} else {reject(err);}});});}function writeFile(filename, data, options) {return new Promise((resolve, reject) => {(_fsPlus || _load_fsPlus()).default.writeFile(filename, data, options, (err, result) => {if (err == null) {resolve(result);} else {reject(err);}});});}function chmod(path, mode) {return new Promise((resolve, reject) => {_fs.default.chmod(path, mode, (err, result) => {if (err == null) {resolve(result);} else {reject(err);}});});}function chown(path, uid, gid) {return new Promise((resolve, reject) => {_fs.default.chown(path, uid, gid, (err, result) => {if (err == null) {resolve(result);} else {reject(err);}});});}function close(fd) {return new Promise((resolve, reject) => {_fs.default.close(fd, err => {if (err == null) {resolve();} else {reject(err);}});});}function lstat(path) {return new Promise((resolve, reject) => {_fs.default.lstat(path, (err, result) => {if (err == null) {resolve(result);} else {reject(err);}});});}function mkdir(path, mode) {return new Promise((resolve, reject) => {_fs.default.mkdir(path, mode, (err, result) => {if (err == null) {resolve(result);} else {reject(err);}});});} /** + * The key difference between 'mv' and 'rename' is that 'mv' works across devices. + * It's not uncommon to have temporary files in a different disk, for instance. + */function mv(sourcePath, destinationPath, options = {}) {return new Promise((resolve, reject) => {(0, (_mv || _load_mv()).default)(sourcePath, destinationPath, options, error => {if (error) {reject(error);} else {resolve();}});});}function open(path, flags, mode = 0o666) {return new Promise((resolve, reject) => {_fs.default.open(path, flags, mode, (err, fd) => {if (err == null) {resolve(fd);} else {reject(err);}});});}function read(fd, buffer, offset, length, position) {return new Promise((resolve, reject) => {_fs.default.read(fd, buffer, offset, length, position, (err, bytesRead) => {if (err == null) {resolve(bytesRead);} else {reject(err);}});});} // `fs.readFile` returns a Buffer unless an encoding is specified. +// This workaround is adapted from the Flow declarations. +const readFile = function (...args) {return new Promise((resolve, reject) => {// $FlowIssue: spread operator doesn't preserve any-type + _fs.default.readFile(...args, (err, result) => {if (err == null) {resolve(result);} else {reject(err);}});});};function readdir(path) {return new Promise((resolve, reject) => {_fs.default.readdir(path, (err, result) => {if (err == null) {resolve(result);} else {reject(err);}});});}function readlink(path) {return new Promise((resolve, reject) => {_fs.default.readlink(path, (err, result) => {if (err == null) {resolve(result);} else {reject(err);}});});}function realpath(path, cache) {return new Promise((resolve, reject) => {_fs.default.realpath(path, cache, (err, result) => {if (err == null) {resolve(result);} else {reject(err);}});});}function access(path, mode) {return new Promise((resolve, reject) => {_fs.default.access(path, mode, err => {if (err == null) {resolve(true);} else {resolve(false);}});});}function stat(path) {return new Promise((resolve, reject) => {_fs.default.stat(path, (err, result) => {if (err == null) {resolve(result);} else {reject(err);}});});}function symlink(source, dest, type) {return new Promise((resolve, reject) => {_fs.default.symlink(source, dest, type, (err, result) => {if (err == null) {resolve(result);} else {reject(err);}});});}function unlink(path) {return new Promise((resolve, reject) => {_fs.default.unlink(path, (err, result) => {if (err == null) {resolve(result);} else {reject(err);}});});}function utimes(path, atime, mtime) {return new Promise((resolve, reject) => {_fs.default.utimes(path, atime, mtime, err => {if (err == null) {resolve();} else {reject(err); } }); }); } -function rmdir(path: string): Promise { +function rmdir(path) { return new Promise((resolve, reject) => { - fs.rmdir(path, err => { + _fs.default.rmdir(path, err => { if (err == null) { resolve(); } else { @@ -630,9 +630,9 @@ function rmdir(path: string): Promise { } }); }); -} +}exports.default = -export default { +{ tempdir, tempfile, findNearestFile, @@ -669,5 +669,4 @@ export default { unlink, utimes, rmdir, - access, -}; + access }; \ No newline at end of file diff --git a/modules/nuclide-commons/humanizeKeystroke.js b/modules/nuclide-commons/humanizeKeystroke.js index 811265c9..6d280a43 100644 --- a/modules/nuclide-commons/humanizeKeystroke.js +++ b/modules/nuclide-commons/humanizeKeystroke.js @@ -1,141 +1,141 @@ -/** - * 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 - * @format - */ - -/* - * adapted from https://github.com/atom/underscore-plus/blob/master/src/underscore-plus.coffee - */ - -const MAC_MODIFIER_KEYMAP = { - alt: '\u2325', - cmd: '\u2318', - ctrl: '\u2303', - down: '\u2193', - enter: '\u23ce', - left: '\u2190', - option: '\u2325', - right: '\u2192', - shift: '\u21e7', - up: '\u2191', -}; - -const NON_MAC_MODIFIER_KEYMAP = { - alt: 'Alt', - cmd: 'Cmd', - ctrl: 'Ctrl', - down: 'Down', - enter: 'Enter', - left: 'Left', - option: 'Alt', - right: 'Right', - shift: 'Shift', - up: 'Up', -}; - -// Human key combos should always explicitly state the shift key. This map is a disambiguator. +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +humanizeKeystroke; /** + * 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. + * + * + * @format + */ /* + * adapted from https://github.com/atom/underscore-plus/blob/master/src/underscore-plus.coffee + */const MAC_MODIFIER_KEYMAP = { alt: '\u2325', cmd: '\u2318', ctrl: '\u2303', down: '\u2193', enter: '\u23ce', left: '\u2190', option: '\u2325', right: '\u2192', shift: '\u21e7', up: '\u2191' };const NON_MAC_MODIFIER_KEYMAP = { alt: 'Alt', cmd: 'Cmd', ctrl: 'Ctrl', down: 'Down', enter: 'Enter', left: 'Left', option: 'Alt', right: 'Right', shift: 'Shift', up: 'Up' }; // Human key combos should always explicitly state the shift key. This map is a disambiguator. // 'shift-version': 'no-shift-version' -const SHIFT_KEYMAP = { - _: '-', - ':': ';', - '?': '/', - '"': "'", - '{': '[', - '}': ']', - '+': '=', - '<': ',', - '>': '.', - '|': '\\', - '~': '`', -}; - -const FN_KEY_RE = /f[0-9]{1,2}/; - -// $FlowIssue -function flatten(arr: Array>): Array { - let flattened = []; - for (const el of arr) { - if (Array.isArray(el)) { - flattened = flattened.concat(flatten(el)); - } else { - flattened.push(el); - } - } - return flattened; -} - -function capitalize(word: string): string { - const first = word[0] || ''; - const rest = word.slice(1); - return first.toUpperCase() + rest; -} - -function humanizeKey(key: string, platform: ?string): string | Array { - if (!key) { - return key; - } - const modifierKeyMap = - platform === 'darwin' ? MAC_MODIFIER_KEYMAP : NON_MAC_MODIFIER_KEYMAP; - if (modifierKeyMap[key]) { - return modifierKeyMap[key]; - } - if (key.length === 1) { - if (SHIFT_KEYMAP[key]) { - return [modifierKeyMap.shift, SHIFT_KEYMAP[key]]; - } - const uppercase = key.toUpperCase(); - if (key === uppercase && uppercase !== key.toLowerCase()) { - return [modifierKeyMap.shift, uppercase]; - } - return uppercase; - } - if (FN_KEY_RE.test(key)) { - return key.toUpperCase(); - } - return platform === 'darwin' ? key : capitalize(key); -} - -/** - * Humanize the keystroke according to platform conventions. This method - * attempts to mirror the text the given keystroke would have if displayed in - * a system menu. - * - * @param keystroke A String keystroke to humanize such as `ctrl-O`. - * @param platform An optional String platform to humanize for (default: `process.platform`). - * @return a humanized representation of the keystroke. - */ -export default function humanizeKeystroke( - keystroke: string, - platform_: ?string, -): string { - let platform = platform_; - if (!keystroke) { - return keystroke; - } - // flowlint-next-line sketchy-null-string:off - platform = platform || process.platform; - const separator = platform === 'darwin' ? '' : '+'; - let key; - let keys; - let splitKeystroke; - const keystrokes = keystroke.split(' '); - const humanizedKeystrokes = []; - for (let i = 0; i < keystrokes.length; i++) { - const currentKeystroke = keystrokes[i]; - splitKeystroke = currentKeystroke.split('-'); - keys = []; - for (let index = 0; index < splitKeystroke.length; index++) { - key = splitKeystroke[index]; - if (key === '' && splitKeystroke[index - 1] === '') { - key = '-'; - } +const SHIFT_KEYMAP = { _: '-', ':': ';', '?': '/', '"': "'", '{': '[', '}': ']', '+': '=', '<': ',', '>': '.', '|': '\\', '~': '`' };const FN_KEY_RE = /f[0-9]{1,2}/; // $FlowIssue +function flatten(arr) {let flattened = [];for (const el of arr) {if (Array.isArray(el)) {flattened = flattened.concat(flatten(el));} else {flattened.push(el);}}return flattened;}function capitalize(word) {const first = word[0] || '';const rest = word.slice(1);return first.toUpperCase() + rest;}function humanizeKey(key, platform) {if (!key) {return key;}const modifierKeyMap = platform === 'darwin' ? MAC_MODIFIER_KEYMAP : NON_MAC_MODIFIER_KEYMAP;if (modifierKeyMap[key]) {return modifierKeyMap[key];}if (key.length === 1) {if (SHIFT_KEYMAP[key]) {return [modifierKeyMap.shift, SHIFT_KEYMAP[key]];}const uppercase = key.toUpperCase();if (key === uppercase && uppercase !== key.toLowerCase()) {return [modifierKeyMap.shift, uppercase];}return uppercase;}if (FN_KEY_RE.test(key)) {return key.toUpperCase();}return platform === 'darwin' ? key : capitalize(key);} /** + * Humanize the keystroke according to platform conventions. This method + * attempts to mirror the text the given keystroke would have if displayed in + * a system menu. + * + * @param keystroke A String keystroke to humanize such as `ctrl-O`. + * @param platform An optional String platform to humanize for (default: `process.platform`). + * @return a humanized representation of the keystroke. + */function humanizeKeystroke(keystroke, platform_) {let platform = platform_;if (!keystroke) {return keystroke;} // flowlint-next-line sketchy-null-string:off + platform = platform || process.platform;const separator = platform === 'darwin' ? '' : '+';let key;let keys;let splitKeystroke;const keystrokes = keystroke.split(' ');const humanizedKeystrokes = [];for (let i = 0; i < keystrokes.length; i++) {const currentKeystroke = keystrokes[i];splitKeystroke = currentKeystroke.split('-');keys = [];for (let index = 0; index < splitKeystroke.length; index++) {key = splitKeystroke[index];if (key === '' && splitKeystroke[index - 1] === '') {key = '-';} if (key) { keys.push(humanizeKey(key, platform)); } @@ -144,4 +144,4 @@ export default function humanizeKeystroke( humanizedKeystrokes.push(keys.join(separator)); } return humanizedKeystrokes.join(' '); -} +} \ No newline at end of file diff --git a/modules/nuclide-commons/matchIndexesToRanges.js b/modules/nuclide-commons/matchIndexesToRanges.js index 73ff81a8..2f059053 100644 --- a/modules/nuclide-commons/matchIndexesToRanges.js +++ b/modules/nuclide-commons/matchIndexesToRanges.js @@ -1,20 +1,20 @@ -/** - * 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 - * @format - */ - -type MatchRange = [/* start */ number, /* end */ number]; - -export default function matchIndexesToRanges( - matchIndexes: Array, -): Array { +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.default = + + + + + + + + + + + + + +matchIndexesToRanges;function matchIndexesToRanges( +matchIndexes) +{ let streakOngoing = false; let start = 0; const ranges = []; @@ -38,4 +38,14 @@ export default function matchIndexesToRanges( } }); return ranges; -} +} /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/memoizeUntilChanged.js b/modules/nuclide-commons/memoizeUntilChanged.js index 93088431..a02eb2df 100644 --- a/modules/nuclide-commons/memoizeUntilChanged.js +++ b/modules/nuclide-commons/memoizeUntilChanged.js @@ -1,101 +1,101 @@ -/** - * 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 - * @format - */ - -import invariant from 'assert'; -import {arrayEqual} from './collection'; - -type memoizeUntilChanged = (( - func: (A, B, C, D) => R, - keySelector_?: (A, B, C, D) => U, - compareKeys_?: (U, U) => boolean, -) => (A, B, C, D) => R) & - (( - func: (A, B, C) => R, - keySelector_?: (A, B, C) => U, - compareKeys_?: (U, U) => boolean, - ) => (A, B, C) => R) & - (( - func: (A, B) => R, - keySelector_?: (A, B) => U, - compareKeys_?: (U, U) => boolean, - ) => (A, B) => R) & - (( - func: (A) => R, - keySelector_?: (A) => U, - compareKeys_?: (U, U) => boolean, - ) => A => R) & - ((func: () => R) => () => R) & - (( - func: (...any: $ReadOnlyArray) => R, - (...any: $ReadOnlyArray) => U, - compareKeys_?: (U, U) => boolean, - ) => (...any: $ReadOnlyArray) => R); +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _collection; + + + + + + + + + + + + +function _load_collection() {return _collection = require('./collection');} + + + + + + + + + + + + + + + + + + + + + + + + + + + /** - * Create a memoized version of the provided function that caches only the latest result. This is - * especially useful for optimizing React component methods without having to worry about - * maintaining state explicitly. For example: - * - * class MyComponent extends React.Component { - * constructor(props) { - * super(props); - * this._computeSomethingExpensive = memoizeUntilChanged(this._computeSomethingExpensive); - * } - * _computeSomethingExpensive(x) { ... } - * render() { - * const thingToRender = this._computeSomethingExpensive(this.props.value); - * return
      {thingToRender}
      ; - * } - * } - * - * Sometimes, you need to customize how the arguments are compared. In this case you can pass a - * key selector function (which derives a single value from the arguments), and an equality function - * (which compares keys). For example: - * - * class MyComponent extends React.Component { - * constructor(props) { - * super(props); - * this._computeSomethingExpensive = memoizeUntilChanged( - * this._computeSomethingExpensive, - * (x: Array, y: Array) => ({x, y}), - * (a, b) => arrayEqual(a.x, b.x) && arrayEqual(a.y, b.y), - * ); - * } - * _computeSomethingExpensive(x: Array, y: Array) { ... } - * render() { - * const thingToRender = this._computeSomethingExpensive(this.props.value); - * return
      {thingToRender}
      ; - * } - * } - */ -export default ((func, keySelector_?, compareKeys_?) => { - invariant( - !(keySelector_ == null && compareKeys_ != null), - "You can't provide a compare function without also providing a key selector.", - ); - - let prevKey = null; - let prevResult; - const keySelector = keySelector_ || DEFAULT_KEY_SELECTOR; - const compareKeys = compareKeys_ || arrayEqual; - return function(...args) { - const key = (keySelector: Function)(...args); - invariant(key != null, 'Key cannot be null'); + * Create a memoized version of the provided function that caches only the latest result. This is + * especially useful for optimizing React component methods without having to worry about + * maintaining state explicitly. For example: + * + * class MyComponent extends React.Component { + * constructor(props) { + * super(props); + * this._computeSomethingExpensive = memoizeUntilChanged(this._computeSomethingExpensive); + * } + * _computeSomethingExpensive(x) { ... } + * render() { + * const thingToRender = this._computeSomethingExpensive(this.props.value); + * return
      {thingToRender}
      ; + * } + * } + * + * Sometimes, you need to customize how the arguments are compared. In this case you can pass a + * key selector function (which derives a single value from the arguments), and an equality function + * (which compares keys). For example: + * + * class MyComponent extends React.Component { + * constructor(props) { + * super(props); + * this._computeSomethingExpensive = memoizeUntilChanged( + * this._computeSomethingExpensive, + * (x: Array, y: Array) => ({x, y}), + * (a, b) => arrayEqual(a.x, b.x) && arrayEqual(a.y, b.y), + * ); + * } + * _computeSomethingExpensive(x: Array, y: Array) { ... } + * render() { + * const thingToRender = this._computeSomethingExpensive(this.props.value); + * return
      {thingToRender}
      ; + * } + * } + */ /** + * 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. + * + * + * @format + */exports.default = (func, keySelector_, compareKeys_) => {if (!!(keySelector_ == null && compareKeys_ != null)) {throw new Error("You can't provide a compare function without also providing a key selector.");}let prevKey = null;let prevResult;const keySelector = keySelector_ || DEFAULT_KEY_SELECTOR;const compareKeys = compareKeys_ || (_collection || _load_collection()).arrayEqual; + return function (...args) { + const key = keySelector(...args);if (!( + key != null)) {throw new Error('Key cannot be null');} if (prevKey == null || !compareKeys(key, prevKey)) { prevKey = key; - prevResult = (func: Function).apply(this, args); + prevResult = func.apply(this, args); } return prevResult; }; -}: memoizeUntilChanged); +}; -const DEFAULT_KEY_SELECTOR = (...args) => args; +const DEFAULT_KEY_SELECTOR = (...args) => args; \ No newline at end of file diff --git a/modules/nuclide-commons/nice.js b/modules/nuclide-commons/nice.js index 61115d1a..14e593e6 100644 --- a/modules/nuclide-commons/nice.js +++ b/modules/nuclide-commons/nice.js @@ -1,107 +1,113 @@ -/** - * 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 - * @format - */ - -import type {LRUCache} from 'lru-cache'; -import type {ObserveProcessOptions, ProcessMessage} from './process'; - -import LRU from 'lru-cache'; -import {Observable} from 'rxjs'; - -import which from './which'; -import {spawn, observeProcess} from './process'; - -const NICE_COMMAND = 'nice'; -const IONICE_COMMAND = 'ionice'; - -export async function niceSafeSpawn( - command: string, - args: Array, - execOptions?: Object, -): Promise { - const nicified = await nicifyCommand(command, args, execOptions); - const processStream = spawn(...nicified).publish(); - const processPromise = processStream.take(1).toPromise(); - processStream.connect(); - return processPromise; -} +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.niceSafeSpawn = undefined;var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));let niceSafeSpawn = exports.niceSafeSpawn = (() => {var _ref = (0, _asyncToGenerator.default)( + + + + + + + + + + + + + + + + + + + + + + + + function* ( + command, + args, + execOptions) + { + const nicified = yield nicifyCommand(command, args, execOptions); + const processStream = (0, (_process || _load_process()).spawn)(...nicified).publish(); + const processPromise = processStream.take(1).toPromise(); + processStream.connect(); + return processPromise; + });return function niceSafeSpawn(_x, _x2, _x3) {return _ref.apply(this, arguments);};})(); /** - * Takes the arguments that you would normally pass to `spawn()` and returns an array of new - * arguments to use to run the command under `nice`. - * - * Example: - * - * ```js - * observeProcess(...(await nicifyCommand('hg', ['diff']))).subscribe(...); - * ``` - * - * See also `scriptifyCommand()` which does a similar thing but for `script`. - */ -async function nicifyCommand( - command: string, - args?: Array, - options: T, -): Promise<[string, Array, T]> { - const fullArgs = [command, ...(args || [])]; - if (await hasNiceCommand()) { - fullArgs.unshift(NICE_COMMAND); - } - if (await hasIoniceCommand()) { - // Leave the process in the Best Effort class (default), but set it to the lowest priority for - // that class. Priorities range from 0-7 with 4 as the default and lower numbers representing - // higher priorities. - // - // See `man ionice` or http://linux.die.net/man/1/ionice - // - // It's not specified by POSIX like `nice` is but since it is included in util-linux which is - // relatively core - // (https://git.kernel.org/cgit/utils/util-linux/util-linux.git/tree/schedutils/ionice.c), I - // think we can assume that it uses this interface if it exists. - fullArgs.unshift(IONICE_COMMAND, '-n', '7'); - } - return [fullArgs[0], fullArgs.slice(1), options]; -} - -const commandAvailabilityCache: LRUCache> = LRU({ - max: 10, - // Realistically this will not change very often so we can cache for long periods of time. We + * Takes the arguments that you would normally pass to `spawn()` and returns an array of new + * arguments to use to run the command under `nice`. + * + * Example: + * + * ```js + * observeProcess(...(await nicifyCommand('hg', ['diff']))).subscribe(...); + * ``` + * + * See also `scriptifyCommand()` which does a similar thing but for `script`. + */let nicifyCommand = (() => {var _ref2 = (0, _asyncToGenerator.default)( + function* ( + command, + args, + options) + { + const fullArgs = [command, ...(args || [])]; + if (yield hasNiceCommand()) { + fullArgs.unshift(NICE_COMMAND); + } + if (yield hasIoniceCommand()) { + // Leave the process in the Best Effort class (default), but set it to the lowest priority for + // that class. Priorities range from 0-7 with 4 as the default and lower numbers representing + // higher priorities. + // + // See `man ionice` or http://linux.die.net/man/1/ionice + // + // It's not specified by POSIX like `nice` is but since it is included in util-linux which is + // relatively core + // (https://git.kernel.org/cgit/utils/util-linux/util-linux.git/tree/schedutils/ionice.c), I + // think we can assume that it uses this interface if it exists. + fullArgs.unshift(IONICE_COMMAND, '-n', '7'); + } + return [fullArgs[0], fullArgs.slice(1), options]; + });return function nicifyCommand(_x4, _x5, _x6) {return _ref2.apply(this, arguments);};})();exports. + + + + + + + + + + + + + + + + + + + + + + + + + + +niceObserveProcess = niceObserveProcess;var _lruCache;function _load_lruCache() {return _lruCache = _interopRequireDefault(require('lru-cache'));}var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _which;function _load_which() {return _which = _interopRequireDefault(require('./which'));}var _process;function _load_process() {return _process = require('./process');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */const NICE_COMMAND = 'nice';const IONICE_COMMAND = 'ionice';const commandAvailabilityCache = (0, (_lruCache || _load_lruCache()).default)({ max: 10, // Realistically this will not change very often so we can cache for long periods of time. We // probably could just check at startup and get away with it, but maybe someone will install // `ionice` and it would be nice to pick that up. - maxAge: 1000 * 60 * 5, // 5 minutes -}); - -function hasNiceCommand(): Promise { - return hasCommand(NICE_COMMAND); -} - -function hasIoniceCommand(): Promise { - return hasCommand(IONICE_COMMAND); -} - -function hasCommand(command: string): Promise { - let result: ?Promise = commandAvailabilityCache.get(command); - if (result == null) { - result = which(command).then(x => x != null); - commandAvailabilityCache.set(command, result); - } - return result; -} - -export function niceObserveProcess( - command: string, - args?: Array, - options?: ObserveProcessOptions, -): Observable { - return Observable.defer(() => - nicifyCommand(command, args, options), - ).switchMap(spawnArgs => observeProcess(...spawnArgs)); -} + maxAge: 1000 * 60 * 5 // 5 minutes +});function hasNiceCommand() {return hasCommand(NICE_COMMAND);}function hasIoniceCommand() {return hasCommand(IONICE_COMMAND);}function hasCommand(command) {let result = commandAvailabilityCache.get(command);if (result == null) {result = (0, (_which || _load_which()).default)(command).then(x => x != null);commandAvailabilityCache.set(command, result);}return result;}function niceObserveProcess(command, args, options) {return _rxjsBundlesRxMinJs.Observable.defer(() => nicifyCommand(command, args, options)).switchMap(spawnArgs => (0, (_process || _load_process()).observeProcess)(...spawnArgs));} \ No newline at end of file diff --git a/modules/nuclide-commons/nuclideUri.js b/modules/nuclide-commons/nuclideUri.js index 0bc223c2..e80f0abf 100644 --- a/modules/nuclide-commons/nuclideUri.js +++ b/modules/nuclide-commons/nuclideUri.js @@ -1,99 +1,99 @@ -/** - * 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 - * @format - */ - -// NuclideUri's are either a local file path, or a URI -// of the form nuclide:// -// -// This package creates, queries and decomposes NuclideUris. +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.__TEST__ = undefined;var _vscodeUri; + + + + + + + + + + + + + + + + +function _load_vscodeUri() {return _vscodeUri = _interopRequireDefault(require('vscode-uri'));} + + + + + + -import LspUri from 'vscode-uri'; -export type NuclideUri = string; -type ParsedUrl = { - hostname: ?string, - path: string, -}; -type ParsedRemoteUrl = { - hostname: string, - path: string, -}; -type ParsedPath = { - root: string, - dir: string, - base: string, - ext: string, - name: string, -}; -import invariant from 'assert'; -// eslint-disable-next-line rulesdir/prefer-nuclide-uri -import pathModule from 'path'; -import os from 'os'; -import {maybeToString} from './string'; -const ARCHIVE_SEPARATOR = '!'; -const KNOWN_ARCHIVE_EXTENSIONS = ['.jar', '.zip']; -const REMOTE_PATH_URI_PREFIX = 'nuclide://'; -// TODO(ljw): following regex is incorrect. A URI scheme must start with -// [A-Za-z] not [0-9_-]. Also, not all schemes require // after them. -const URI_PREFIX_REGEX = /^[A-Za-z0-9_-]+:\/\/.*/; -function isRemote(uri: NuclideUri): boolean { - return uri.startsWith(REMOTE_PATH_URI_PREFIX); -} -// When restoring Atom state on load, Atom mangles our remote URIs by + + + + + + +var _path = _interopRequireDefault(require('path')); + +var _os = _interopRequireDefault(require('os'));var _string; +function _load_string() {return _string = require('./string');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */ // NuclideUri's are either a local file path, or a URI +// of the form nuclide:// +// +// This package creates, queries and decomposes NuclideUris. +const ARCHIVE_SEPARATOR = '!'; // eslint-disable-next-line rulesdir/prefer-nuclide-uri +const KNOWN_ARCHIVE_EXTENSIONS = ['.jar', '.zip'];const REMOTE_PATH_URI_PREFIX = 'nuclide://'; // TODO(ljw): following regex is incorrect. A URI scheme must start with +// [A-Za-z] not [0-9_-]. Also, not all schemes require // after them. +const URI_PREFIX_REGEX = /^[A-Za-z0-9_-]+:\/\/.*/;function isRemote(uri) {return uri.startsWith(REMOTE_PATH_URI_PREFIX);} // When restoring Atom state on load, Atom mangles our remote URIs by // removing one of the '/'s. These TextBuffers/TextEditors live for a short time // and are destroyed during Nuclide startup. // On Windows, we further mangle the colon into an underscore to avoid an invalid drive prefix. -function isBrokenDeserializedUri(uri: ?NuclideUri): boolean { - return uri != null && uri.match(/nuclide[:_][\\/][^/]/) != null; -} - +function isBrokenDeserializedUri(uri) {return uri != null && uri.match(/nuclide[:_][\\/][^/]/) != null;} // Atom often puts its URIs in places where we'd expect to see Nuclide URIs (or plain paths) -function isAtomUri(uri: NuclideUri): boolean { +function isAtomUri(uri) { return uri.startsWith('atom://'); } -function isUri(uri: string): boolean { +function isUri(uri) { return URI_PREFIX_REGEX.test(uri); } -function isLocal(uri: NuclideUri): boolean { +function isLocal(uri) { return !isRemote(uri) && !isUri(uri) && !isAtomUri(uri); } -function createRemoteUri(hostname: string, remotePath: string): string { - invariant( - remotePath != null && remotePath !== '', - 'NuclideUri must include a path.', - ); +function createRemoteUri(hostname, remotePath) {if (!( + + remotePath != null && remotePath !== '')) {throw new Error( + 'NuclideUri must include a path.');} + return `nuclide://${hostname}${remotePath}`; } -function isInArchive(uri: NuclideUri): boolean { +function isInArchive(uri) { if (isAtomUri(uri) || uri.indexOf(ARCHIVE_SEPARATOR) < 0) { return false; } for ( - let i = uri.indexOf(ARCHIVE_SEPARATOR); - i >= 0; - i = uri.indexOf(ARCHIVE_SEPARATOR, i + 1) - ) { + let i = uri.indexOf(ARCHIVE_SEPARATOR); + i >= 0; + i = uri.indexOf(ARCHIVE_SEPARATOR, i + 1)) + { if (_isArchiveSeparator(uri, i)) { return true; } @@ -101,12 +101,12 @@ function isInArchive(uri: NuclideUri): boolean { return false; } -function ancestorOutsideArchive(uri: NuclideUri): NuclideUri { +function ancestorOutsideArchive(uri) { for ( - let i = uri.indexOf(ARCHIVE_SEPARATOR); - i >= 0; - i = uri.indexOf(ARCHIVE_SEPARATOR, i + 1) - ) { + let i = uri.indexOf(ARCHIVE_SEPARATOR); + i >= 0; + i = uri.indexOf(ARCHIVE_SEPARATOR, i + 1)) + { if (_isArchiveSeparator(uri, i)) { return uri.substring(0, i); } @@ -115,75 +115,75 @@ function ancestorOutsideArchive(uri: NuclideUri): NuclideUri { } /** - * Parses valid Nuclide URIs into the hostname and path components. - * Throws an Error on invalid URIs. Invalid URIs are: - * 1) Any URI that does not start with 'nuclide://' protocol. - * 2) A URI starting with 'nuclide://' that doesn't contain either a hostname or a path - * - * Everything that does not contain a '://' is assumed to be a local path. Both POSIX and Windows - * paths are legal - */ -function parse(uri: NuclideUri): ParsedUrl { + * Parses valid Nuclide URIs into the hostname and path components. + * Throws an Error on invalid URIs. Invalid URIs are: + * 1) Any URI that does not start with 'nuclide://' protocol. + * 2) A URI starting with 'nuclide://' that doesn't contain either a hostname or a path + * + * Everything that does not contain a '://' is assumed to be a local path. Both POSIX and Windows + * paths are legal + */ +function parse(uri) { if (uri.startsWith(REMOTE_PATH_URI_PREFIX)) { const hostAndPath = uri.substr(REMOTE_PATH_URI_PREFIX.length); - const hostSep = hostAndPath.indexOf('/'); + const hostSep = hostAndPath.indexOf('/');if (!( - invariant( - hostSep !== -1, - `Remote URIs must contain a hostname and a path. Failed to parse ${uri}`, - ); - const hostname = hostAndPath.substr(0, hostSep); - invariant( - hostname !== '', - `Remote URIs must contain a hostname. Failed to parse ${uri}`, - ); + hostSep !== -1)) {throw new Error( + `Remote URIs must contain a hostname and a path. Failed to parse ${uri}`);} - const path = hostAndPath.substr(hostSep); - invariant( - !_endsWithArchiveSeparator(uri), - `Path cannot end with archive separator. Failed to parse ${uri}`, - ); - return {hostname, path}; - } - invariant( - !_endsWithArchiveSeparator(uri), - `Path cannot end with archive separator. Failed to parse ${uri}`, - ); - return {hostname: null, path: uri}; + const hostname = hostAndPath.substr(0, hostSep);if (!( + + hostname !== '')) {throw new Error( + `Remote URIs must contain a hostname. Failed to parse ${uri}`);} + + + const path = hostAndPath.substr(hostSep);if (! + + !_endsWithArchiveSeparator(uri)) {throw new Error( + `Path cannot end with archive separator. Failed to parse ${uri}`);} + + return { hostname, path }; + }if (! + + + !_endsWithArchiveSeparator(uri)) {throw new Error( + `Path cannot end with archive separator. Failed to parse ${uri}`);} + + return { hostname: null, path: uri }; } -function parseRemoteUri(remoteUri: NuclideUri): ParsedRemoteUrl { +function parseRemoteUri(remoteUri) { if (!isRemote(remoteUri)) { throw new Error('Expected remote uri. Got ' + remoteUri); } - const parsedUri = parse(remoteUri); - invariant( - // flowlint-next-line sketchy-null-string:off - parsedUri.hostname, - `Remote Nuclide URIs must contain hostnames, '${maybeToString( - parsedUri.hostname, - )}' found while parsing '${remoteUri}'`, - ); + const parsedUri = parse(remoteUri);if (! + + // flowlint-next-line sketchy-null-string:off + parsedUri.hostname) {throw new Error( + `Remote Nuclide URIs must contain hostnames, '${(0, (_string || _load_string()).maybeToString)( + parsedUri.hostname) + }' found while parsing '${remoteUri}'`);} + // Explicitly copying object properties appeases Flow's "maybe" type handling. Using the `...` // operator causes null/undefined errors, and `Object.assign` bypasses type checking. return { hostname: parsedUri.hostname, - path: parsedUri.path, - }; + path: parsedUri.path }; + } -function getPath(uri: NuclideUri): string { +function getPath(uri) { return parse(uri).path; } -function getHostname(remoteUri: NuclideUri): string { +function getHostname(remoteUri) { return parseRemoteUri(remoteUri).hostname; } -function getHostnameOpt(remoteUri: ?NuclideUri): ?string { +function getHostnameOpt(remoteUri) { if (remoteUri == null || !isRemote(remoteUri)) { return null; } @@ -191,28 +191,28 @@ function getHostnameOpt(remoteUri: ?NuclideUri): ?string { return getHostname(remoteUri); } -function join(uri: NuclideUri, ...relativePath: Array): NuclideUri { +function join(uri, ...relativePath) { _testForIllegalUri(uri); const uriPathModule = _pathModuleFor(uri); if (isRemote(uri)) { - const {hostname, path} = parseRemoteUri(uri); + const { hostname, path } = parseRemoteUri(uri); relativePath.splice(0, 0, path); _archiveEncodeArrayInPlace(uriPathModule, relativePath); return _archiveDecode( - uriPathModule, - createRemoteUri(hostname, uriPathModule.join.apply(null, relativePath)), - ); + uriPathModule, + createRemoteUri(hostname, uriPathModule.join.apply(null, relativePath))); + } else { relativePath.splice(0, 0, uri); _archiveEncodeArrayInPlace(uriPathModule, relativePath); return _archiveDecode( - uriPathModule, - uriPathModule.join.apply(null, relativePath), - ); + uriPathModule, + uriPathModule.join.apply(null, relativePath)); + } } -function archiveJoin(uri: NuclideUri, path: string): NuclideUri { +function archiveJoin(uri, path) { _testForIllegalUri(uri); if (!KNOWN_ARCHIVE_EXTENSIONS.some(ext => uri.endsWith(ext))) { throw new Error(`Cannot archiveJoin with non-archive ${uri} and ${path}`); @@ -220,98 +220,98 @@ function archiveJoin(uri: NuclideUri, path: string): NuclideUri { return uri + ARCHIVE_SEPARATOR + path; } -function normalize(uri: NuclideUri): NuclideUri { +function normalize(uri) { _testForIllegalUri(uri); const uriPathModule = _pathModuleFor(uri); if (isRemote(uri)) { - const {hostname, path} = parseRemoteUri(uri); + const { hostname, path } = parseRemoteUri(uri); const normal = _archiveDecode( - uriPathModule, - uriPathModule.normalize(_archiveEncode(uriPathModule, path)), - ); + uriPathModule, + uriPathModule.normalize(_archiveEncode(uriPathModule, path))); + return createRemoteUri(hostname, normal); } else { return _archiveDecode( - uriPathModule, - uriPathModule.normalize(_archiveEncode(uriPathModule, uri)), - ); + uriPathModule, + uriPathModule.normalize(_archiveEncode(uriPathModule, uri))); + } } -function normalizeDir(uri: NuclideUri): NuclideUri { +function normalizeDir(uri) { return ensureTrailingSeparator(normalize(uri)); } -function getParent(uri: NuclideUri): NuclideUri { +function getParent(uri) { // TODO: Is this different than dirname? return normalize(join(uri, '..')); } -function relative(uri: NuclideUri, other: NuclideUri): string { +function relative(uri, other) { _testForIllegalUri(uri); const uriPathModule = _pathModuleFor(uri); const remote = isRemote(uri); if ( - remote !== isRemote(other) || - (remote && getHostname(uri) !== getHostname(other)) - ) { + remote !== isRemote(other) || + remote && getHostname(uri) !== getHostname(other)) + { throw new Error( - `Cannot relative urls on different hosts: ${uri} and ${other}`, - ); + `Cannot relative urls on different hosts: ${uri} and ${other}`); + } const uriEncode = _archiveEncode(uriPathModule, remote ? getPath(uri) : uri); const otherEncode = _archiveEncode( - uriPathModule, - remote ? getPath(other) : other, - ); + uriPathModule, + remote ? getPath(other) : other); + return _archiveDecode( - uriPathModule, - uriPathModule.relative( - _matchTrailingArchive(uriEncode, otherEncode), - _matchTrailingArchive(otherEncode, uriEncode), - ), - ); + uriPathModule, + uriPathModule.relative( + _matchTrailingArchive(uriEncode, otherEncode), + _matchTrailingArchive(otherEncode, uriEncode))); + + } -function basename(uri: NuclideUri, ext: string = ''): string { +function basename(uri, ext = '') { _testForIllegalUri(uri); const uriPathModule = _pathModuleFor(uri); return _archiveDecode( - uriPathModule, - uriPathModule.basename(_archiveEncode(uriPathModule, getPath(uri)), ext), - ); + uriPathModule, + uriPathModule.basename(_archiveEncode(uriPathModule, getPath(uri)), ext)); + } -function dirname(uri: NuclideUri): NuclideUri { +function dirname(uri) { _testForIllegalUri(uri); const uriPathModule = _pathModuleFor(uri); if (isRemote(uri)) { - const {hostname, path} = parseRemoteUri(uri); + const { hostname, path } = parseRemoteUri(uri); return createRemoteUri( - hostname, - _archiveDecode( - uriPathModule, - uriPathModule.dirname(_archiveEncode(uriPathModule, path)), - ), - ); + hostname, + _archiveDecode( + uriPathModule, + uriPathModule.dirname(_archiveEncode(uriPathModule, path)))); + + } else { return _archiveDecode( - uriPathModule, - uriPathModule.dirname(_archiveEncode(uriPathModule, uri)), - ); + uriPathModule, + uriPathModule.dirname(_archiveEncode(uriPathModule, uri))); + } } -function extname(uri: NuclideUri): string { +function extname(uri) { _testForIllegalUri(uri); const uriPathModule = _pathModuleFor(uri); return _archiveDecode( - uriPathModule, - uriPathModule.extname(_archiveEncode(uriPathModule, getPath(uri))), - ); + uriPathModule, + uriPathModule.extname(_archiveEncode(uriPathModule, getPath(uri)))); + } -function stripExtension(uri: NuclideUri): NuclideUri { +function stripExtension(uri) { _testForIllegalUri(uri); const ext = extname(uri); if (ext.length === 0) { @@ -321,11 +321,11 @@ function stripExtension(uri: NuclideUri): NuclideUri { return uri.slice(0, -1 * ext.length); } -function _isWindowsPath(path: string): boolean { - return _pathModuleFor(path) === pathModule.win32; +function _isWindowsPath(path) { + return _pathModuleFor(path) === _path.default.win32; } -function _getWindowsPathFromWindowsFileUri(uri: string): ?string { +function _getWindowsPathFromWindowsFileUri(uri) { const prefix = 'file://'; if (!uri.startsWith(prefix)) { return null; @@ -336,12 +336,12 @@ function _getWindowsPathFromWindowsFileUri(uri: string): ?string { } /** - * uri is either a file: uri, or a nuclide: uri. - * must convert file: uri's to just a path for atom. - * - * Returns null if not a valid file: URI. - */ -function uriToNuclideUri(uri: string): ?string { + * uri is either a file: uri, or a nuclide: uri. + * must convert file: uri's to just a path for atom. + * + * Returns null if not a valid file: URI. + */ +function uriToNuclideUri(uri) { // TODO(ljw): the following check is incorrect. It's designed to support // two-slash file URLs of the form "file://c:\path". But those are invalid // file URLs, and indeed it fails to %-escape "file://c:\My%20Documents". @@ -355,7 +355,7 @@ function uriToNuclideUri(uri: string): ?string { return windowsPathFromUri; } - const lspUri = LspUri.parse(uri); + const lspUri = (_vscodeUri || _load_vscodeUri()).default.parse(uri); if (lspUri.scheme === 'file' && lspUri.path) { // only handle real files for now. @@ -368,21 +368,21 @@ function uriToNuclideUri(uri: string): ?string { } /** - * Converts local paths to file: URI's. Leaves remote URI's alone. - */ -function nuclideUriToUri(uri: NuclideUri): string { + * Converts local paths to file: URI's. Leaves remote URI's alone. + */ +function nuclideUriToUri(uri) { _testForIllegalUri(uri); if (isRemote(uri)) { return uri; } else { - return LspUri.file(uri).toString(); + return (_vscodeUri || _load_vscodeUri()).default.file(uri).toString(); } } /** - * Returns true if child is equal to, or is a proper child of parent. - */ -function contains(parent: NuclideUri, child: NuclideUri): boolean { + * Returns true if child is equal to, or is a proper child of parent. + */ +function contains(parent, child) { _testForIllegalUri(parent); _testForIllegalUri(child); @@ -410,9 +410,9 @@ function contains(parent: NuclideUri, child: NuclideUri): boolean { } return ( - parent.startsWith(child) && - (endsWithSeparator(parent) || _isArchiveSeparator(child, parent.length)) - ); + parent.startsWith(child) && ( + endsWithSeparator(parent) || _isArchiveSeparator(child, parent.length))); + } if (!child.startsWith(parent)) { @@ -427,15 +427,15 @@ function contains(parent: NuclideUri, child: NuclideUri): boolean { return ( _isArchiveSeparator(child, parent.length) || - child.slice(parent.length).startsWith(uriPathModule.sep) - ); + child.slice(parent.length).startsWith(uriPathModule.sep)); + } /** - * Filter an array of paths to contain only the collapsed root paths, e.g. - * [a/b/c, a/, c/d/, c/d/e] collapses to [a/, c/d/] - */ -function collapse(paths: Array): Array { + * Filter an array of paths to contain only the collapsed root paths, e.g. + * [a/b/c, a/, c/d/, c/d/e] collapses to [a/, c/d/] + */ +function collapse(paths) { return paths.filter(p => !paths.some(fp => contains(fp, p) && fp !== p)); } @@ -443,10 +443,10 @@ const hostFormatters = []; // A formatter which may shorten hostnames. // Returns null if the formatter won't shorten the hostname. -export type HostnameFormatter = (uri: NuclideUri) => ?string; + // Registers a host formatter for nuclideUriToDisplayString -function registerHostnameFormatter(formatter: HostnameFormatter): IDisposable { +function registerHostnameFormatter(formatter) { hostFormatters.push(formatter); return { dispose: () => { @@ -454,15 +454,15 @@ function registerHostnameFormatter(formatter: HostnameFormatter): IDisposable { if (index >= 0) { hostFormatters.splice(index, 1); } - }, - }; + } }; + } /** - * NuclideUris should never be shown to humans. - * This function returns a human usable string. - */ -function nuclideUriToDisplayString(uri: NuclideUri): string { + * NuclideUris should never be shown to humans. + * This function returns a human usable string. + */ +function nuclideUriToDisplayString(uri) { _testForIllegalUri(uri); if (isRemote(uri)) { let hostname = getHostname(uri); @@ -480,7 +480,7 @@ function nuclideUriToDisplayString(uri: NuclideUri): string { } } -function ensureTrailingSeparator(uri: NuclideUri): NuclideUri { +function ensureTrailingSeparator(uri) { _testForIllegalUri(uri); const uriPathModule = _pathModuleFor(uri); if (uri.endsWith(uriPathModule.sep)) { @@ -490,7 +490,7 @@ function ensureTrailingSeparator(uri: NuclideUri): NuclideUri { return uri + uriPathModule.sep; } -function trimTrailingSeparator(uri: NuclideUri): NuclideUri { +function trimTrailingSeparator(uri) { _testForIllegalUri(uri); const uriPathModule = _pathModuleFor(uri); let stripped = uri; @@ -502,13 +502,13 @@ function trimTrailingSeparator(uri: NuclideUri): NuclideUri { return stripped; } -function endsWithSeparator(uri: NuclideUri): boolean { +function endsWithSeparator(uri) { _testForIllegalUri(uri); const uriPathModule = _pathModuleFor(uri); return uri.endsWith(uriPathModule.sep); } -function isAbsolute(uri: NuclideUri): boolean { +function isAbsolute(uri) { _testForIllegalUri(uri); if (isRemote(uri)) { return true; @@ -518,28 +518,28 @@ function isAbsolute(uri: NuclideUri): boolean { } } -function resolve(uri: NuclideUri, ...paths: Array): NuclideUri { +function resolve(uri, ...paths) { _testForIllegalUri(uri); const uriPathModule = _pathModuleFor(uri); if (isRemote(uri)) { - const {hostname, path} = parseRemoteUri(uri); + const { hostname, path } = parseRemoteUri(uri); paths.splice(0, 0, path); _archiveEncodeArrayInPlace(uriPathModule, paths); return createRemoteUri( - hostname, - _archiveDecode(uriPathModule, uriPathModule.resolve.apply(null, paths)), - ); + hostname, + _archiveDecode(uriPathModule, uriPathModule.resolve.apply(null, paths))); + } else { paths.splice(0, 0, uri); _archiveEncodeArrayInPlace(uriPathModule, paths); return _archiveDecode( - uriPathModule, - uriPathModule.resolve.apply(null, paths), - ); + uriPathModule, + uriPathModule.resolve.apply(null, paths)); + } } -function expandHomeDir(uri: NuclideUri): NuclideUri { +function expandHomeDir(uri) { _testForIllegalUri(uri); // Do not expand non home relative uris @@ -550,11 +550,11 @@ function expandHomeDir(uri: NuclideUri): NuclideUri { // "home" on Windows is %UserProfile%. Note that Windows environment variables // are NOT case sensitive, but process.env is a magic object that wraps GetEnvironmentVariableW // on Windows, so asking for any case is expected to work. - const {HOME, UserProfile} = process.env; + const { HOME, UserProfile } = process.env; - const isWindows = !isRemote(uri) && os.platform() === 'win32'; - const homePath = isWindows ? UserProfile : HOME; - invariant(homePath != null); + const isWindows = !isRemote(uri) && _os.default.platform() === 'win32'; + const homePath = isWindows ? UserProfile : HOME;if (!( + homePath != null)) {throw new Error('Invariant violation: "homePath != null"');} if (uri === '~') { return homePath; @@ -565,58 +565,58 @@ function expandHomeDir(uri: NuclideUri): NuclideUri { return uri; } - return pathModule.resolve(homePath, uri.replace('~', '.')); + return _path.default.resolve(homePath, uri.replace('~', '.')); } /** - * Splits a string containing local paths by an OS-specific path delimiter - * Useful for splitting env variables such as PATH - * - * Since remote URI might contain the delimiter, only local paths are allowed. - */ -function splitPathList(paths: string): Array { - invariant( - paths.indexOf(REMOTE_PATH_URI_PREFIX) < 0, - 'Splitting remote URIs is not supported', - ); + * Splits a string containing local paths by an OS-specific path delimiter + * Useful for splitting env variables such as PATH + * + * Since remote URI might contain the delimiter, only local paths are allowed. + */ +function splitPathList(paths) {if (!( + + paths.indexOf(REMOTE_PATH_URI_PREFIX) < 0)) {throw new Error( + 'Splitting remote URIs is not supported');} + const uriPathModule = _pathModuleFor(paths); return paths.split(uriPathModule.delimiter); } /** - * Joins an array of local paths with an OS-specific path delimiter into a single string. - * Useful for constructing env variables such as PATH - * - * Since remote URI might contain the delimiter, only local paths are allowed. - */ -function joinPathList(paths: Array): string { + * Joins an array of local paths with an OS-specific path delimiter into a single string. + * Useful for constructing env variables such as PATH + * + * Since remote URI might contain the delimiter, only local paths are allowed. + */ +function joinPathList(paths) { if (paths.length === 0) { return ''; - } + }if (! + + + paths.every(path => !isRemote(path))) {throw new Error( + 'Joining of remote URIs is not supported');} - invariant( - paths.every(path => !isRemote(path)), - 'Joining of remote URIs is not supported', - ); const uriPathModule = _pathModuleFor(paths[0]); return paths.join(uriPathModule.delimiter); } /** - * This function prepends the given relative path with a "current-folder" prefix - * which is `./` on *nix and .\ on Windows - */ -function ensureLocalPrefix(uri: NuclideUri): NuclideUri { + * This function prepends the given relative path with a "current-folder" prefix + * which is `./` on *nix and .\ on Windows + */ +function ensureLocalPrefix(uri) { _testForIllegalUri(uri); - const uriPathModule = _pathModuleFor(uri); + const uriPathModule = _pathModuleFor(uri);if (! + + !isRemote(uri)) {throw new Error('Local prefix can not be added to a remote path');}if (! + + !isAbsolute(uri)) {throw new Error( + 'Local prefix can not be added to an absolute path');} - invariant(!isRemote(uri), 'Local prefix can not be added to a remote path'); - invariant( - !isAbsolute(uri), - 'Local prefix can not be added to an absolute path', - ); const localPrefix = `.${uriPathModule.sep}`; if (uri.startsWith(localPrefix)) { @@ -626,35 +626,35 @@ function ensureLocalPrefix(uri: NuclideUri): NuclideUri { return localPrefix + uri; } -function isRoot(uri: NuclideUri): boolean { +function isRoot(uri) { _testForIllegalUri(uri); return dirname(uri) === uri; } -function parsePath(uri: NuclideUri): ParsedPath { +function parsePath(uri) { _testForIllegalUri(uri); const uriPathModule = _pathModuleFor(uri); if (!isInArchive(uri)) { return uriPathModule.parse(getPath(uri)); } else { const parsed = uriPathModule.parse( - _archiveEncode(uriPathModule, getPath(uri)), - ); + _archiveEncode(uriPathModule, getPath(uri))); + return { root: _archiveDecode(uriPathModule, parsed.root), dir: _archiveDecode(uriPathModule, parsed.dir), base: _archiveDecode(uriPathModule, parsed.base), ext: _archiveDecode(uriPathModule, parsed.ext), - name: _archiveDecode(uriPathModule, parsed.name), - }; + name: _archiveDecode(uriPathModule, parsed.name) }; + } } -function pathSeparatorFor(uri: NuclideUri): string { +function pathSeparatorFor(uri) { return _pathModuleFor(uri).sep; } -function split(uri: NuclideUri): Array { +function split(uri) { const parts = []; let current = uri; let parent = dirname(current); @@ -673,82 +673,82 @@ function split(uri: NuclideUri): Array { return parts; } -function hasKnownArchiveExtension(uri: NuclideUri): boolean { +function hasKnownArchiveExtension(uri) { return KNOWN_ARCHIVE_EXTENSIONS.some(ext => uri.endsWith(ext)); } -function _pathModuleFor(uri: NuclideUri): typeof pathModule { - invariant( - !_endsWithArchiveSeparator(uri), - `Path cannot end with archive separator. Failed to determine path module for ${uri}`, - ); - if (uri.startsWith(pathModule.posix.sep)) { - return pathModule.posix; +function _pathModuleFor(uri) {if (! + + !_endsWithArchiveSeparator(uri)) {throw new Error( + `Path cannot end with archive separator. Failed to determine path module for ${uri}`);} + + if (uri.startsWith(_path.default.posix.sep)) { + return _path.default.posix; } if (uri.indexOf('://') > -1) { - return pathModule.posix; + return _path.default.posix; } - if (uri[1] === ':' && uri[2] === pathModule.win32.sep) { - return pathModule.win32; + if (uri[1] === ':' && uri[2] === _path.default.win32.sep) { + return _path.default.win32; } if ( - uri.split(pathModule.win32.sep).length > - uri.split(pathModule.posix.sep).length - ) { - return pathModule.win32; + uri.split(_path.default.win32.sep).length > + uri.split(_path.default.posix.sep).length) + { + return _path.default.win32; } else { - return pathModule.posix; + return _path.default.posix; } } // Runs _archiveEncode in-place on array, and returns argument for convenience. function _archiveEncodeArrayInPlace( - uriPathModule: typeof pathModule, - array: Array, -): Array { - array.forEach((uri, i, a) => (a[i] = _archiveEncode(uriPathModule, uri))); +uriPathModule, +array) +{ + array.forEach((uri, i, a) => a[i] = _archiveEncode(uriPathModule, uri)); return array; } // This adds a native separator after every archive separator // so that the native path handling code sees them. function _archiveEncode( - uriPathModule: typeof pathModule, - uri: NuclideUri, -): NuclideUri { +uriPathModule, +uri) +{ if (uri.indexOf(ARCHIVE_SEPARATOR) < 0) { return uri; } return KNOWN_ARCHIVE_EXTENSIONS.reduce( - (acc, ext) => - acc.replace( - `${ext}${ARCHIVE_SEPARATOR}`, - `${ext}${ARCHIVE_SEPARATOR}${uriPathModule.sep}`, - ), - uri, - ); + (acc, ext) => + acc.replace( + `${ext}${ARCHIVE_SEPARATOR}`, + `${ext}${ARCHIVE_SEPARATOR}${uriPathModule.sep}`), + + uri); + } // This is the inverse of `encodeArchiveSeparators()` to put things // back after the native path handler has run. function _archiveDecode( - uriPathModule: typeof pathModule, - uri: NuclideUri, -): NuclideUri { +uriPathModule, +uri) +{ if (uri.indexOf(ARCHIVE_SEPARATOR) < 0) { return uri; } return _trimArchiveSuffix( - KNOWN_ARCHIVE_EXTENSIONS.reduce( - (acc, ext) => - acc.replace( - `${ext}${ARCHIVE_SEPARATOR}${uriPathModule.sep}`, - `${ext}${ARCHIVE_SEPARATOR}`, - ), - uri, - ), - ); + KNOWN_ARCHIVE_EXTENSIONS.reduce( + (acc, ext) => + acc.replace( + `${ext}${ARCHIVE_SEPARATOR}${uriPathModule.sep}`, + `${ext}${ARCHIVE_SEPARATOR}`), + + uri)); + + } // When working with encoded uri's, the archive separator is part of the name @@ -762,19 +762,19 @@ function _archiveDecode( // /etc/file.zip!/abc // We need to add a trailing '!' to the first one so uriPathModule can see that // the first contains the second. -function _matchTrailingArchive(uri: string, other: string): string { +function _matchTrailingArchive(uri, other) { if ( - uri.length < other.length && - other.startsWith(uri) && - _isArchiveSeparator(other, uri.length) - ) { + uri.length < other.length && + other.startsWith(uri) && + _isArchiveSeparator(other, uri.length)) + { return uri + ARCHIVE_SEPARATOR; } else { return uri; } } -function _trimArchiveSuffix(path: string): string { +function _trimArchiveSuffix(path) { if (_endsWithArchiveSeparator(path)) { return path.substring(0, path.length - ARCHIVE_SEPARATOR.length); } else { @@ -782,27 +782,27 @@ function _trimArchiveSuffix(path: string): string { } } -function _endsWithArchiveSeparator(path: string): boolean { +function _endsWithArchiveSeparator(path) { return _isArchiveSeparator(path, path.length - 1); } -function _isArchiveSeparator(path: string, index: number): boolean { +function _isArchiveSeparator(path, index) { return ( path.length > index && path.charAt(index) === ARCHIVE_SEPARATOR && KNOWN_ARCHIVE_EXTENSIONS.some(ext => { const extStart = index - ext.length; return path.indexOf(ext, extStart) === extStart; - }) - ); + })); + } -function _testForIllegalUri(uri: ?NuclideUri): void { +function _testForIllegalUri(uri) { if (uri != null) { if (_endsWithArchiveSeparator(uri)) { throw new Error( - `Path operation invoked on URI ending with ${ARCHIVE_SEPARATOR}: ${uri}`, - ); + `Path operation invoked on URI ending with ${ARCHIVE_SEPARATOR}: ${uri}`); + } } } @@ -811,24 +811,24 @@ const NUCLIDE_URI_TYPE_NAME = 'NuclideUri'; // If mustBeRemote is present then remote-ness must match, otherwise remote-ness // is ignored. -function validate(uri: NuclideUri, mustBeRemote?: boolean): void { +function validate(uri, mustBeRemote) { // Be a little extra paranoid to catch places where the type system may be weak. - invariant(uri != null, 'Unexpected null NuclideUri'); - invariant( - typeof uri === 'string', - `Unexpected NuclideUri type: ${String(uri)}`, - ); + if (!(uri != null)) {throw new Error('Unexpected null NuclideUri');}if (!( + + typeof uri === 'string')) {throw new Error( + `Unexpected NuclideUri type: ${String(uri)}`);} + if (isRemote(uri)) { - parse(uri); - invariant(mustBeRemote !== false, 'Expected remote NuclideUri'); - } else { - invariant(uri !== '', 'NuclideUri must contain a non-empty path'); - invariant(mustBeRemote !== true, 'Expected local NuclideUri'); + parse(uri);if (!( + mustBeRemote !== false)) {throw new Error('Expected remote NuclideUri');} + } else {if (!( + uri !== '')) {throw new Error('NuclideUri must contain a non-empty path');}if (!( + mustBeRemote !== true)) {throw new Error('Expected local NuclideUri');} } -} +}exports.default = -export default { +{ basename, dirname, extname, @@ -873,9 +873,8 @@ export default { hasKnownArchiveExtension, ARCHIVE_SEPARATOR, KNOWN_ARCHIVE_EXTENSIONS, - NUCLIDE_URI_TYPE_NAME, -}; + NUCLIDE_URI_TYPE_NAME }; + -export const __TEST__ = { - _pathModuleFor, -}; +const __TEST__ = exports.__TEST__ = { + _pathModuleFor }; \ No newline at end of file diff --git a/modules/nuclide-commons/observable.js b/modules/nuclide-commons/observable.js index ee6b4fc7..e646a008 100644 --- a/modules/nuclide-commons/observable.js +++ b/modules/nuclide-commons/observable.js @@ -1,3 +1,603 @@ +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.SingletonExecutor = exports.nextAnimationFrame = exports.macrotask = exports.microtask = undefined;var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +splitStream = splitStream;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +bufferUntil = bufferUntil;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +cacheWhileSubscribed = cacheWhileSubscribed;exports. + + + + + + + + + + + + +diffSets = diffSets;exports. + + + + + + + + + + + + + + + + + + + +reconcileSetDiffs = reconcileSetDiffs;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +reconcileSets = reconcileSets;exports. + + + + + + + + +toggle = toggle;exports. + + + + + + + + +compact = compact;exports. + + + + + + + +takeWhileInclusive = takeWhileInclusive;exports. + + + + + + + + + + + + + + + + + + + + + + + +concatLatest = concatLatest;exports. + + + + + + + + + + + + + + + + + + + + + + + +throttle = throttle;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +completingSwitchMap = completingSwitchMap;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +fastDebounce = fastDebounce;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +fromAbortablePromise = fromAbortablePromise;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +toAbortablePromise = toAbortablePromise;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + +takeUntilAbort = takeUntilAbort;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +poll = poll;var _UniversalDisposable;function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('./UniversalDisposable'));}var _domexception;function _load_domexception() {return _domexception = _interopRequireDefault(require('domexception'));}var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _AbortController;function _load_AbortController() {return _AbortController = _interopRequireDefault(require('./AbortController'));}var _collection;function _load_collection() {return _collection = require('./collection');}var _debounce;function _load_debounce() {return _debounce = _interopRequireDefault(require('./debounce'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * Splits a stream of strings on newlines. + * Includes the newlines in the resulting stream (if includeNewlines is true). + * Sends any non-newline terminated data before closing. + * Does not ensure a trailing newline. + */function splitStream(input, includeNewlines = true) {return _rxjsBundlesRxMinJs.Observable.create(observer => {let current = '';function onEnd() {if (current !== '') {observer.next(current);current = '';}}return input.subscribe(value => {const lines = value.split('\n');lines[0] = current + lines[0];current = lines.pop();if (includeNewlines) {lines.forEach(line => observer.next(line + '\n'));} else {lines.forEach(line => observer.next(line));}}, error => {onEnd();observer.error(error);}, () => {onEnd();observer.complete();});});} /** + * Buffers until the predicate matches an element, then opens a new buffer. + * + * @param stream - The observable to buffer + * @param predicate - A function that will be called every time an element is emitted from the + * source. The predicate is passed the current element as well as the buffer at that point + * (which includes the element). IMPORTANT: DO NOT MUTATE THE BUFFER. It returns a boolean + * specifying whether to complete the buffer (and begin a new one). + */ // Note: DOMException is usable in Chrome but not in Node. /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,13 +606,9 @@ * 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 + * * @format - */ - -/* global requestAnimationFrame, cancelAnimationFrame */ - -// NOTE: Custom operators that require arguments should be written as higher-order functions. That + */ /* global requestAnimationFrame, cancelAnimationFrame */ // NOTE: Custom operators that require arguments should be written as higher-order functions. That // is, they should accept the arguments and return a function that accepts only an observable. This // allows a nice ergonomic way of using them with '.let()' (or a potential future pipe operator): // @@ -23,582 +619,148 @@ // Observable.of('hey', 'everybody') // .let(makeExciting()) // .subscribe(x => console.log(x)); - -import type {AbortSignal} from './AbortController'; - -import UniversalDisposable from './UniversalDisposable'; -import invariant from 'assert'; -// Note: DOMException is usable in Chrome but not in Node. -import DOMException from 'domexception'; -import {Observable, ReplaySubject, Subject} from 'rxjs'; -import AbortController from './AbortController'; -import {setDifference} from './collection'; -import debounce from './debounce'; - -/** - * Splits a stream of strings on newlines. - * Includes the newlines in the resulting stream (if includeNewlines is true). - * Sends any non-newline terminated data before closing. - * Does not ensure a trailing newline. - */ -export function splitStream( - input: Observable, - includeNewlines?: boolean = true, -): Observable { - return Observable.create(observer => { - let current: string = ''; - - function onEnd() { - if (current !== '') { - observer.next(current); - current = ''; - } - } - - return input.subscribe( - value => { - const lines = value.split('\n'); - lines[0] = current + lines[0]; - current = lines.pop(); - if (includeNewlines) { - lines.forEach(line => observer.next(line + '\n')); - } else { - lines.forEach(line => observer.next(line)); - } - }, - error => { - onEnd(); - observer.error(error); - }, - () => { - onEnd(); - observer.complete(); - }, - ); - }); -} - -/** - * Buffers until the predicate matches an element, then opens a new buffer. - * - * @param stream - The observable to buffer - * @param predicate - A function that will be called every time an element is emitted from the - * source. The predicate is passed the current element as well as the buffer at that point - * (which includes the element). IMPORTANT: DO NOT MUTATE THE BUFFER. It returns a boolean - * specifying whether to complete the buffer (and begin a new one). - */ -export function bufferUntil( - condition: (item: T, buffer: Array) => boolean, -): (Observable) => Observable> { - return (stream: Observable) => - Observable.create(observer => { - let buffer = null; - const flush = () => { - if (buffer != null) { - observer.next(buffer); - buffer = null; - } - }; - return stream.subscribe( - x => { - if (buffer == null) { - buffer = []; - } - buffer.push(x); - if (condition(x, buffer)) { - flush(); - } - }, - err => { - flush(); - observer.error(err); - }, - () => { - flush(); - observer.complete(); - }, - ); - }); -} - -/** - * Caches the latest element as long as there are subscribers. This is useful so that if consumers - * unsubscribe and then subscribe much later, they do not get an ancient cached value. - * - * This is intended to be used with cold Observables. If you have a hot Observable, `cache(1)` will - * be just fine because the hot Observable will continue producing values even when there are no - * subscribers, so you can be assured that the cached values are up-to-date. - */ -export function cacheWhileSubscribed(input: Observable): Observable { - return input.multicast(() => new ReplaySubject(1)).refCount(); -} - -type Diff = { - added: Set, - removed: Set, -}; - -/** - * Given a stream of sets, return a stream of diffs. - * **IMPORTANT:** These sets are assumed to be immutable by convention. Don't mutate them! - */ -export function diffSets( - hash?: (v: T) => any, -): (Observable>) => Observable> { - return (sets: Observable>) => - Observable.concat( - Observable.of(new Set()), // Always start with no items with an empty set - sets, - ) - .pairwise() - .map(([previous, next]) => ({ - added: setDifference(next, previous, hash), - removed: setDifference(previous, next, hash), - })) - .filter(diff => diff.added.size > 0 || diff.removed.size > 0); -} - -/** - * Give a stream of diffs, perform an action for each added item and dispose of the returned - * disposable when the item is removed. - */ -export function reconcileSetDiffs( - diffs: Observable>, - addAction: (addedItem: T) => IDisposable, - hash_?: (v: T) => any, -): IDisposable { - const hash = hash_ || (x => x); - const itemsToDisposables = new Map(); - const disposeItem = item => { - const disposable = itemsToDisposables.get(hash(item)); - invariant(disposable != null); - disposable.dispose(); - itemsToDisposables.delete(item); - }; - const disposeAll = () => { - itemsToDisposables.forEach(disposable => { - disposable.dispose(); - }); - itemsToDisposables.clear(); - }; - - return new UniversalDisposable( - diffs.subscribe(diff => { - // For every item that got added, perform the add action. - diff.added.forEach(item => { - itemsToDisposables.set(hash(item), addAction(item)); - }); - - // "Undo" the add action for each item that got removed. - diff.removed.forEach(disposeItem); - }), - disposeAll, - ); -} - -/** - * Given a stream of sets, perform a side-effect whenever an item is added (i.e. is present in a - * set but wasn't in the previous set in the stream), and a corresponding cleanup when it's removed. - * **IMPORTANT:** These sets are assumed to be immutable by convention. Don't mutate them! - * - * Example: - * - * const dogs = Observable.of( - * new Set([{name: 'Winston', id: 1}, {name: 'Penelope', id: 2}]), - * new Set([{name: 'Winston', id: 1}]), - * ); - * const disposable = reconcileSets( - * dogs, - * dog => { - * const notification = atom.notifications.addSuccess( - * `${dog.name} was added!`, - * {dismissable: true}, - * ); - * return new Disposable(() => { notification.dismiss(); }); - * }, - * dog => dog.id, - * ); - * - * The above code will first add notifications saying "Winston was added!" and "Penelope was - * added!", then dismiss the "Penelope" notification. Since the Winston object is in the final set - * of the dogs observable, his notification will remain until `disposable.dispose()` is called, at - * which point the cleanup for all remaining items will be performed. - */ -export function reconcileSets( - sets: Observable>, - addAction: (addedItem: T) => IDisposable, - hash?: (v: T) => any, -): IDisposable { - const diffs = sets.let(diffSets(hash)); - return reconcileSetDiffs(diffs, addAction, hash); -} - -export function toggle( - toggler: Observable, -): (Observable) => Observable { - return (source: Observable) => - toggler - .distinctUntilChanged() - .switchMap(enabled => (enabled ? source : Observable.empty())); -} - -export function compact(source: Observable): Observable { - // Flow does not understand the semantics of `filter` - return (source.filter(x => x != null): any); -} - -/** - * Like `takeWhile`, but includes the first item that doesn't match the predicate. - */ -export function takeWhileInclusive( - predicate: (value: T) => boolean, -): (Observable) => Observable { - return (source: Observable) => - Observable.create(observer => - source.subscribe( - x => { - observer.next(x); - if (!predicate(x)) { - observer.complete(); - } - }, - err => { - observer.error(err); - }, - () => { - observer.complete(); - }, - ), - ); -} - -// Concatenate the latest values from each input observable into one big list. +function bufferUntil(condition) {return stream => _rxjsBundlesRxMinJs.Observable.create(observer => {let buffer = null;const flush = () => {if (buffer != null) {observer.next(buffer);buffer = null;}};return stream.subscribe(x => {if (buffer == null) {buffer = [];}buffer.push(x);if (condition(x, buffer)) {flush();}}, err => {flush();observer.error(err);}, () => {flush();observer.complete();});});} /** + * Caches the latest element as long as there are subscribers. This is useful so that if consumers + * unsubscribe and then subscribe much later, they do not get an ancient cached value. + * + * This is intended to be used with cold Observables. If you have a hot Observable, `cache(1)` will + * be just fine because the hot Observable will continue producing values even when there are no + * subscribers, so you can be assured that the cached values are up-to-date. + */function cacheWhileSubscribed(input) {return input.multicast(() => new _rxjsBundlesRxMinJs.ReplaySubject(1)).refCount();} /** + * Given a stream of sets, return a stream of diffs. + * **IMPORTANT:** These sets are assumed to be immutable by convention. Don't mutate them! + */function diffSets(hash) {return sets => _rxjsBundlesRxMinJs.Observable.concat(_rxjsBundlesRxMinJs.Observable.of(new Set()), // Always start with no items with an empty set + sets).pairwise().map(([previous, next]) => ({ added: (0, (_collection || _load_collection()).setDifference)(next, previous, hash), removed: (0, (_collection || _load_collection()).setDifference)(previous, next, hash) })).filter(diff => diff.added.size > 0 || diff.removed.size > 0);} /** + * Give a stream of diffs, perform an action for each added item and dispose of the returned + * disposable when the item is removed. + */function reconcileSetDiffs(diffs, addAction, hash_) {const hash = hash_ || (x => x);const itemsToDisposables = new Map();const disposeItem = item => {const disposable = itemsToDisposables.get(hash(item));if (!(disposable != null)) {throw new Error('Invariant violation: "disposable != null"');}disposable.dispose();itemsToDisposables.delete(item);};const disposeAll = () => {itemsToDisposables.forEach(disposable => {disposable.dispose();});itemsToDisposables.clear();};return new (_UniversalDisposable || _load_UniversalDisposable()).default(diffs.subscribe(diff => {// For every item that got added, perform the add action. + diff.added.forEach(item => {itemsToDisposables.set(hash(item), addAction(item));}); // "Undo" the add action for each item that got removed. + diff.removed.forEach(disposeItem);}), disposeAll);} /** + * Given a stream of sets, perform a side-effect whenever an item is added (i.e. is present in a + * set but wasn't in the previous set in the stream), and a corresponding cleanup when it's removed. + * **IMPORTANT:** These sets are assumed to be immutable by convention. Don't mutate them! + * + * Example: + * + * const dogs = Observable.of( + * new Set([{name: 'Winston', id: 1}, {name: 'Penelope', id: 2}]), + * new Set([{name: 'Winston', id: 1}]), + * ); + * const disposable = reconcileSets( + * dogs, + * dog => { + * const notification = atom.notifications.addSuccess( + * `${dog.name} was added!`, + * {dismissable: true}, + * ); + * return new Disposable(() => { notification.dismiss(); }); + * }, + * dog => dog.id, + * ); + * + * The above code will first add notifications saying "Winston was added!" and "Penelope was + * added!", then dismiss the "Penelope" notification. Since the Winston object is in the final set + * of the dogs observable, his notification will remain until `disposable.dispose()` is called, at + * which point the cleanup for all remaining items will be performed. + */function reconcileSets(sets, addAction, hash) {const diffs = sets.let(diffSets(hash));return reconcileSetDiffs(diffs, addAction, hash);}function toggle(toggler) {return source => toggler.distinctUntilChanged().switchMap(enabled => enabled ? source : _rxjsBundlesRxMinJs.Observable.empty());}function compact(source) {// Flow does not understand the semantics of `filter` + return source.filter(x => x != null);} /** + * Like `takeWhile`, but includes the first item that doesn't match the predicate. + */function takeWhileInclusive(predicate) {return source => _rxjsBundlesRxMinJs.Observable.create(observer => source.subscribe(x => {observer.next(x);if (!predicate(x)) {observer.complete();}}, err => {observer.error(err);}, () => {observer.complete();}));} // Concatenate the latest values from each input observable into one big list. // Observables who have not emitted a value yet are treated as empty. -export function concatLatest( - ...observables: Array>> -): Observable> { - // First, tag all input observables with their index. - // Flow errors with ambiguity without the explicit annotation. - const tagged: Array, number]>> = observables.map( - (observable, index) => observable.map(list => [list, index]), - ); - return Observable.merge(...tagged) - .scan((accumulator, [list, index]) => { - accumulator[index] = list; - return accumulator; - }, observables.map(x => [])) - .map(accumulator => [].concat(...accumulator)); -} - -type ThrottleOptions = { - // Should the first element be emitted immeditately? Defaults to true. - leading?: boolean, -}; - -/** - * A more sensible alternative to RxJS's throttle/audit/sample operators. - */ -export function throttle( - duration: - | number - | Observable - | ((value: T) => Observable | Promise), - options_: ?ThrottleOptions, -): (Observable) => Observable { - return (source: Observable) => { - const options = options_ || {}; - const leading = options.leading !== false; - let audit; - switch (typeof duration) { - case 'number': - audit = obs => obs.auditTime(duration); - break; - case 'function': - audit = obs => obs.audit(duration); - break; - default: - audit = obs => obs.audit(() => duration); - } - - if (!leading) { - return audit(source); - } - - return Observable.create(observer => { - const connectableSource = source.publish(); - const throttled = Observable.merge( - connectableSource.take(1), - audit(connectableSource.skip(1)), - ); - return new UniversalDisposable( - throttled.subscribe(observer), - connectableSource.connect(), - ); - }); - }; -} - -/** - * Returns a new function which takes an `observable` and returns - * `observable.switchMap(project)`, except that it completes - * when the outer observable completes. - * - * Example: - * - * Observable.of(1) - * .let(completingSwitchMap(x => Observable.never())) - * - * ends up returning an Observable that completes immediately. - * With a regular switchMap, this would never terminate. - */ -export function completingSwitchMap( - project: (input: T, index: number) => rxjs$ObservableInput, -): (Observable) => Observable { - // An alternative implementation is to materialize the input observable, +function concatLatest(...observables) {// First, tag all input observables with their index. + const tagged = observables.map((observable, index) => observable.map(list => [list, index]));return _rxjsBundlesRxMinJs.Observable.merge(...tagged).scan((accumulator, [list, index]) => {accumulator[index] = list;return accumulator;}, observables.map(x => [])).map(accumulator => [].concat(...accumulator));} /** + * A more sensible alternative to RxJS's throttle/audit/sample operators. + */function throttle(duration, options_) {return source => {const options = options_ || {};const leading = options.leading !== false;let audit;switch (typeof duration) {case 'number':audit = obs => obs.auditTime(duration);break;case 'function':audit = obs => obs.audit(duration);break;default:audit = obs => obs.audit(() => duration);}if (!leading) {return audit(source);}return _rxjsBundlesRxMinJs.Observable.create(observer => {const connectableSource = source.publish();const throttled = _rxjsBundlesRxMinJs.Observable.merge(connectableSource.take(1), audit(connectableSource.skip(1)));return new (_UniversalDisposable || _load_UniversalDisposable()).default(throttled.subscribe(observer), connectableSource.connect());});};} /** + * Returns a new function which takes an `observable` and returns + * `observable.switchMap(project)`, except that it completes + * when the outer observable completes. + * + * Example: + * + * Observable.of(1) + * .let(completingSwitchMap(x => Observable.never())) + * + * ends up returning an Observable that completes immediately. + * With a regular switchMap, this would never terminate. + */function completingSwitchMap(project) {// An alternative implementation is to materialize the input observable, // but this avoids the creation of extra notifier objects. - const completedSymbol = Symbol('completed'); - return (observable: Observable) => - Observable.concat( - observable, - Observable.of((completedSymbol: any)), - ).switchMap((input, index) => { - if (input === completedSymbol) { - return Observable.empty(); - } - return project(input, index); - }); -} - -/** - * RxJS's debounceTime is actually fairly inefficient: - * on each event, it always clears its interval and [creates a new one][1]. - * Until this is fixed, this uses our debounce implementation which - * reuses a timeout and just sets a timestamp when possible. - * - * This may seem like a micro-optimization but we often use debounces - * for very hot events, like keypresses. Exceeding the frame budget can easily lead - * to increased key latency! - * - * [1]: https://github.com/ReactiveX/rxjs/blob/master/src/operators/debounceTime.ts#L106 - */ -export function fastDebounce( - delay: number, -): (Observable) => Observable { - return (observable: Observable) => - Observable.create(observer => { - const debouncedNext = debounce((x: T) => observer.next(x), delay); - const subscription = observable.subscribe( - debouncedNext, - observer.error.bind(observer), - observer.complete.bind(observer), - ); - return new UniversalDisposable(subscription, debouncedNext); - }); -} - -export const microtask = Observable.create(observer => { - process.nextTick(() => { - observer.next(); - observer.complete(); - }); -}); - -export const macrotask = Observable.create(observer => { - const timerId = setImmediate(() => { - observer.next(); - observer.complete(); - }); - return () => { - clearImmediate(timerId); - }; -}); - -export const nextAnimationFrame = Observable.create(observer => { - if (typeof requestAnimationFrame === 'undefined') { - throw new Error('This util can only be used in Atom'); - } - const id = requestAnimationFrame(() => { - observer.next(); - observer.complete(); - }); - return () => { - cancelAnimationFrame(id); - }; -}); - -/** - * Creates an Observable around an abortable promise. - * Unsubscriptions are forwarded to the AbortController as an `abort()`. - * Example usage (with an abortable fetch): - * - * fromPromise(signal => fetch(url, {...options, signal})) - * .switchMap(....) - * - * Note that this can take a normal `() => Promise` too - * (in which case this acts as just a plain `Observable.defer`). - */ -export function fromAbortablePromise( - func: (signal: AbortSignal) => Promise, -): Observable { - return Observable.create(observer => { - let completed = false; - const abortController = new AbortController(); - func(abortController.signal).then( - value => { - completed = true; - observer.next(value); - observer.complete(); - }, - error => { - completed = true; - observer.error(error); - }, - ); - return () => { - if (!completed) { - abortController.abort(); - // If the promise adheres to the spec, it should throw. + const completedSymbol = Symbol('completed');return observable => _rxjsBundlesRxMinJs.Observable.concat(observable, _rxjsBundlesRxMinJs.Observable.of(completedSymbol)).switchMap((input, index) => {if (input === completedSymbol) {return _rxjsBundlesRxMinJs.Observable.empty();}return project(input, index);});} /** + * RxJS's debounceTime is actually fairly inefficient: + * on each event, it always clears its interval and [creates a new one][1]. + * Until this is fixed, this uses our debounce implementation which + * reuses a timeout and just sets a timestamp when possible. + * + * This may seem like a micro-optimization but we often use debounces + * for very hot events, like keypresses. Exceeding the frame budget can easily lead + * to increased key latency! + * + * [1]: https://github.com/ReactiveX/rxjs/blob/master/src/operators/debounceTime.ts#L106 + */function fastDebounce(delay) {return observable => _rxjsBundlesRxMinJs.Observable.create(observer => {const debouncedNext = (0, (_debounce || _load_debounce()).default)(x => observer.next(x), delay);const subscription = observable.subscribe(debouncedNext, observer.error.bind(observer), observer.complete.bind(observer));return new (_UniversalDisposable || _load_UniversalDisposable()).default(subscription, debouncedNext);});}const microtask = exports.microtask = _rxjsBundlesRxMinJs.Observable.create(observer => {process.nextTick(() => {observer.next();observer.complete();});});const macrotask = exports.macrotask = _rxjsBundlesRxMinJs.Observable.create(observer => {const timerId = setImmediate(() => {observer.next();observer.complete();});return () => {clearImmediate(timerId);};});const nextAnimationFrame = exports.nextAnimationFrame = _rxjsBundlesRxMinJs.Observable.create(observer => {if (typeof requestAnimationFrame === 'undefined') {throw new Error('This util can only be used in Atom');}const id = requestAnimationFrame(() => {observer.next();observer.complete();});return () => {cancelAnimationFrame(id);};}); /** + * Creates an Observable around an abortable promise. + * Unsubscriptions are forwarded to the AbortController as an `abort()`. + * Example usage (with an abortable fetch): + * + * fromPromise(signal => fetch(url, {...options, signal})) + * .switchMap(....) + * + * Note that this can take a normal `() => Promise` too + * (in which case this acts as just a plain `Observable.defer`). + */function fromAbortablePromise(func) {return _rxjsBundlesRxMinJs.Observable.create(observer => {let completed = false;const abortController = new (_AbortController || _load_AbortController()).default();func(abortController.signal).then(value => {completed = true;observer.next(value);observer.complete();}, error => {completed = true;observer.error(error);});return () => {if (!completed) {abortController.abort(); // If the promise adheres to the spec, it should throw. // The error will be captured above but go into the void. - } - }; - }); -} - -/** - * Converts an observable + AbortSignal into a cancellable Promise, - * which rejects with an AbortError DOMException on abort. - * Useful when writing the internals of a cancellable promise. - * - * Usage: - * - * function abortableFunction(arg1: blah, options?: {signal?: AbortSignal}): Promise { - * return toPromise( - * observableFunction(arg1, options), - * options && options.signal, - * ); - * } - * - * Could eventually be replaced by Observable.first if - * https://github.com/whatwg/dom/issues/544 goes through. - * - * It's currently unclear if this should be usable with let/pipe: - * https://github.com/ReactiveX/rxjs/issues/3445 - */ -export function toAbortablePromise( - observable: Observable, - signal?: ?AbortSignal, -): Promise { - if (signal == null) { - return observable.toPromise(); - } - if (signal.aborted) { - return Promise.reject(DOMException('Aborted', 'AbortError')); - } - return observable - .race( - Observable.fromEvent(signal, 'abort').map(() => { - throw new DOMException('Aborted', 'AbortError'); - }), - ) - .toPromise(); -} - -/** - * When using Observables with AbortSignals, be sure to use this - - * it's really easy to miss the case when the signal is already aborted! - * Recommended to use this with let/pipe: - * - * myObservable - * .let(obs => takeUntilAbort(obs, signal)) - */ -export function takeUntilAbort( - observable: Observable, - signal: AbortSignal, -): Observable { - return Observable.defer(() => { - if (signal.aborted) { - return Observable.empty(); - } - return observable.takeUntil(Observable.fromEvent(signal, 'abort')); - }); -} - -// Executes tasks. Ensures that at most one task is running at a time. + }};});} /** + * Converts an observable + AbortSignal into a cancellable Promise, + * which rejects with an AbortError DOMException on abort. + * Useful when writing the internals of a cancellable promise. + * + * Usage: + * + * function abortableFunction(arg1: blah, options?: {signal?: AbortSignal}): Promise { + * return toPromise( + * observableFunction(arg1, options), + * options && options.signal, + * ); + * } + * + * Could eventually be replaced by Observable.first if + * https://github.com/whatwg/dom/issues/544 goes through. + * + * It's currently unclear if this should be usable with let/pipe: + * https://github.com/ReactiveX/rxjs/issues/3445 + */function toAbortablePromise(observable, signal) {if (signal == null) {return observable.toPromise();}if (signal.aborted) {return Promise.reject((0, (_domexception || _load_domexception()).default)('Aborted', 'AbortError'));}return observable.race(_rxjsBundlesRxMinJs.Observable.fromEvent(signal, 'abort').map(() => {throw new (_domexception || _load_domexception()).default('Aborted', 'AbortError');})).toPromise();} /** + * When using Observables with AbortSignals, be sure to use this - + * it's really easy to miss the case when the signal is already aborted! + * Recommended to use this with let/pipe: + * + * myObservable + * .let(obs => takeUntilAbort(obs, signal)) + */function takeUntilAbort(observable, signal) {return _rxjsBundlesRxMinJs.Observable.defer(() => {if (signal.aborted) {return _rxjsBundlesRxMinJs.Observable.empty();}return observable.takeUntil(_rxjsBundlesRxMinJs.Observable.fromEvent(signal, 'abort'));});} // Executes tasks. Ensures that at most one task is running at a time. // This class is handy for expensive tasks like processes, provided // you never want the result of a previous task after a new task has started. -export class SingletonExecutor { - _abortController: ?AbortController = null; - - // Executes(subscribes to) the task. +class SingletonExecutor {constructor() {this._abortController = null;} // Executes(subscribes to) the task. // Will terminate(unsubscribe) to any previously executing task. // Subsequent executes() will terminate this task if called before // this task completes. - async execute(createTask: Observable): Promise { - // Kill any previously running processes - this.cancel(); - - // Start a new process - const controller = new AbortController(); - this._abortController = controller; - - // Wait for the process to complete or be canceled ... - try { - return await toAbortablePromise(createTask, controller.signal); - } finally { - // ... and always clean up if we haven't been canceled already. - if (controller === this._abortController) { - this._abortController = null; - } - } - } - - isExecuting(): boolean { - return this._abortController != null; - } - - // Cancels any currently executing tasks. - cancel(): void { - if (this._abortController != null) { - this._abortController.abort(); - this._abortController = null; - } - } -} - -/** - * Repeatedly subscribe to an observable every `delay` milliseconds, waiting for the observable to - * complete each time. This is preferable to, say, `Observable.interval(d).switchMap(() => source)` - * because, in the case that `source` takes longer than `d` milliseconds to produce a value, that - * formulation will never produce a value (while continuing to incur the overhead of subscribing to - * source). - * - * Example: - * - * // Ask what time it is every second until it's Friday. - * runCommand('date') - * .let(poll(1000)) - * .filter(output => output.startsWith('Fri')) - * .take(1) - * .subscribe(() => { - * console.log("IT'S FRIDAY!!") - * }); - * - */ -export function poll(delay: number): (Observable) => Observable { - return (source: Observable) => - Observable.defer(() => { - const delays = new Subject(); - return delays - .switchMap(n => Observable.timer(n)) - .merge(Observable.of(null)) - .switchMap(() => { - const subscribedAt = Date.now(); - return source.do({ - complete: () => { - const timeElapsed = Date.now() - subscribedAt; - delays.next(Math.max(0, delay - timeElapsed)); - }, - }); - }); - }); -} + execute(createTask) {var _this = this;return (0, _asyncToGenerator.default)(function* () {// Kill any previously running processes + _this.cancel(); // Start a new process + const controller = new (_AbortController || _load_AbortController()).default();_this._abortController = controller; // Wait for the process to complete or be canceled ... + try {return yield toAbortablePromise(createTask, controller.signal);} finally {// ... and always clean up if we haven't been canceled already. + if (controller === _this._abortController) {_this._abortController = null;}}})();}isExecuting() {return this._abortController != null;} // Cancels any currently executing tasks. + cancel() {if (this._abortController != null) {this._abortController.abort();this._abortController = null;}}}exports.SingletonExecutor = SingletonExecutor; /** + * Repeatedly subscribe to an observable every `delay` milliseconds, waiting for the observable to + * complete each time. This is preferable to, say, `Observable.interval(d).switchMap(() => source)` + * because, in the case that `source` takes longer than `d` milliseconds to produce a value, that + * formulation will never produce a value (while continuing to incur the overhead of subscribing to + * source). + * + * Example: + * + * // Ask what time it is every second until it's Friday. + * runCommand('date') + * .let(poll(1000)) + * .filter(output => output.startsWith('Fri')) + * .take(1) + * .subscribe(() => { + * console.log("IT'S FRIDAY!!") + * }); + * + */function poll(delay) {return source => _rxjsBundlesRxMinJs.Observable.defer(() => {const delays = new _rxjsBundlesRxMinJs.Subject();return delays.switchMap(n => _rxjsBundlesRxMinJs.Observable.timer(n)).merge(_rxjsBundlesRxMinJs.Observable.of(null)).switchMap(() => {const subscribedAt = Date.now();return source.do({ complete: () => {const timeElapsed = Date.now() - subscribedAt;delays.next(Math.max(0, delay - timeElapsed));} });});});} \ No newline at end of file diff --git a/modules/nuclide-commons/package.js b/modules/nuclide-commons/package.js index 8928ceab..d117d7d8 100644 --- a/modules/nuclide-commons/package.js +++ b/modules/nuclide-commons/package.js @@ -1,29 +1,35 @@ -/** - * 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 - * @format - */ - -import fs from 'fs'; -import invariant from 'assert'; - -// Use a regex and not the "semver" module so the result here is the same +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + + + + + + +getPackageMinorVersion = getPackageMinorVersion;var _fs = _interopRequireDefault(require('fs'));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} // Use a regex and not the "semver" module so the result here is the same // as from python code. -const SEMVERISH_RE = /^(\d+)\.(\d+)\.(\d+)(?:-([a-z0-9.-]+))?$/; - -export function getPackageMinorVersion(packageJsonPath: string): string { - const pkgJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); - const match = SEMVERISH_RE.exec(pkgJson.version); - invariant(match); - // const majorVersion = match[1]; - const minorVersion = match[2]; - // const patchVersion = match[3]; +const SEMVERISH_RE = /^(\d+)\.(\d+)\.(\d+)(?:-([a-z0-9.-]+))?$/; /** + * 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. + * + * + * @format + */function getPackageMinorVersion(packageJsonPath) {const pkgJson = JSON.parse(_fs.default.readFileSync(packageJsonPath, 'utf8'));const match = SEMVERISH_RE.exec(pkgJson.version);if (!match) {throw new Error('Invariant violation: "match"');} // const majorVersion = match[1]; + const minorVersion = match[2]; // const patchVersion = match[3]; // const prereleaseVersion = match[4]; - return minorVersion; -} + return minorVersion;} \ No newline at end of file diff --git a/modules/nuclide-commons/path-uri.js b/modules/nuclide-commons/path-uri.js index b38e80d1..883e453b 100644 --- a/modules/nuclide-commons/path-uri.js +++ b/modules/nuclide-commons/path-uri.js @@ -1,35 +1,45 @@ -/** - * 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 - * @format - */ - -import url from 'url'; - -export function pathToUri(path: string): string { - // TODO(ljw): this is not a valid way of constructing URIs. +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + +pathToUri = pathToUri;exports. + + + + + + + + + +uriToPath = uriToPath;var _url = _interopRequireDefault(require('url'));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function pathToUri(path) {// TODO(ljw): this is not a valid way of constructing URIs. // The format is "file://server/absolute%20path" where // percent-escaping is to be used inside the path for all unsafe characters. // This function fails to work with does-style paths "c:\path", // fails to work with UNC-style paths "\\server\path", // and fails to escape. - return 'file://' + path; -} - -export function uriToPath(uri: string): string { - // TODO: this will think that "c:\file.txt" uses the protocol "c", + return 'file://' + path;} /** + * 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. + * + * + * @format + */function uriToPath(uri) {// TODO: this will think that "c:\file.txt" uses the protocol "c", // rather than being a local filename. It also fails to recognize the host, // e.g. "file://server/path" vs "file://localhost/path" vs "file:///path". - const components = url.parse(uri); - // Some filename returned from hhvm does not have protocol. - if (components.protocol !== 'file:' && components.protocol != null) { - throw new Error(`unexpected file protocol. Got: ${components.protocol}`); - } - return (components.pathname || '') + (components.hash || ''); -} + const components = _url.default.parse(uri); // Some filename returned from hhvm does not have protocol. + if (components.protocol !== 'file:' && components.protocol != null) {throw new Error(`unexpected file protocol. Got: ${components.protocol}`);}return (components.pathname || '') + (components.hash || '');} \ No newline at end of file diff --git a/modules/nuclide-commons/performanceNow.js b/modules/nuclide-commons/performanceNow.js index 12914cb0..e8e060d8 100644 --- a/modules/nuclide-commons/performanceNow.js +++ b/modules/nuclide-commons/performanceNow.js @@ -1,30 +1,30 @@ -/** - * 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 - * @format - */ +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); /** + * 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. + * + * + * @format + */ /* global performance */ /** - * Polyfill for performance.now that works both on Atom (chrome) and node. - * It returns a monotonically increasing timer in milliseconds. - * - * Usage: - * const now = performanceNow(); - * // ... code you want to benchmark ... - * const timeItTookInMilliseconds = performanceNow() - now; - */ + * Polyfill for performance.now that works both on Atom (chrome) and node. + * It returns a monotonically increasing timer in milliseconds. + * + * Usage: + * const now = performanceNow(); + * // ... code you want to benchmark ... + * const timeItTookInMilliseconds = performanceNow() - now; + */exports.default = -export default (typeof performance !== 'undefined' - ? (): number => performance.now() - : (): number => { - const [seconds, nanoseconds] = process.hrtime(); - return seconds * 1000 + nanoseconds / 1000000; - }); +typeof performance !== 'undefined' ? +() => performance.now() : +() => { + const [seconds, nanoseconds] = process.hrtime(); + return seconds * 1000 + nanoseconds / 1000000; +}; \ No newline at end of file diff --git a/modules/nuclide-commons/process.js b/modules/nuclide-commons/process.js index de2b3856..f08d7e7d 100644 --- a/modules/nuclide-commons/process.js +++ b/modules/nuclide-commons/process.js @@ -1,16 +1,1106 @@ +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.killUnixProcessTree = exports.loggedCalls = exports.ProcessLoggingEvent = exports.ProcessTimeoutError = exports.MaxBufferExceededError = exports.ProcessSystemError = exports.ProcessExitError = exports.memoryUsagePerPid = exports.psTree = exports.getChildrenOfProcess = exports.getOriginalEnvironment = exports.LOG_CATEGORY = undefined;var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));let getOriginalEnvironment = exports.getOriginalEnvironment = (() => {var _ref6 = (0, _asyncToGenerator.default)( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + function* () { + yield new Promise(function (resolve) { + whenShellEnvironmentLoaded(resolve); + }); + if (cachedOriginalEnvironment != null) { + return cachedOriginalEnvironment; + } + + const { NUCLIDE_ORIGINAL_ENV } = process.env; + if (NUCLIDE_ORIGINAL_ENV != null && NUCLIDE_ORIGINAL_ENV.trim() !== '') { + const envString = new Buffer(NUCLIDE_ORIGINAL_ENV, 'base64').toString(); + cachedOriginalEnvironment = {}; + for (const envVar of envString.split('\0')) { + // envVar should look like A=value_of_A + const equalIndex = envVar.indexOf('='); + if (equalIndex !== -1) { + cachedOriginalEnvironment[ + envVar.substring(0, equalIndex)] = + envVar.substring(equalIndex + 1); + } + } + // Guard against invalid original environments. + if (!Object.keys(cachedOriginalEnvironment).length) { + cachedOriginalEnvironment = process.env; + } + } else { + cachedOriginalEnvironment = process.env; + } + return cachedOriginalEnvironment; + });return function getOriginalEnvironment() {return _ref6.apply(this, arguments);};})(); + /** - * 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 - * @format - */ + * Returns a string suitable for including in displayed error messages. + */let getChildrenOfProcess = exports.getChildrenOfProcess = (() => {var _ref7 = (0, _asyncToGenerator.default)( + + + + + + + + + + + + + function* ( + processId) + { + const processes = yield psTree(); + + return processes.filter(function (processInfo) {return processInfo.parentPid === processId;}); + });return function getChildrenOfProcess(_x) {return _ref7.apply(this, arguments);};})(); + +/** + * Get a list of descendants, sorted by increasing depth (including the one with the provided pid). + */let getDescendantsOfProcess = (() => {var _ref8 = (0, _asyncToGenerator.default)( + function* ( + pid) + { + const processes = yield psTree(); + let rootProcessInfo; + const pidToChildren = new (_collection || _load_collection()).MultiMap(); + processes.forEach(function (info) { + if (info.pid === pid) { + rootProcessInfo = info; + } + pidToChildren.add(info.parentPid, info); + }); + const descendants = rootProcessInfo == null ? [] : [rootProcessInfo]; + // Walk through the array, adding the children of the current element to the end. This + // breadth-first traversal means that the elements will be sorted by depth. + for (let i = 0; i < descendants.length; i++) { + const info = descendants[i]; + const children = pidToChildren.get(info.pid); + descendants.push(...Array.from(children)); + } + return descendants; + });return function getDescendantsOfProcess(_x2) {return _ref8.apply(this, arguments);};})();let psTree = exports.psTree = (() => {var _ref9 = (0, _asyncToGenerator.default)( + + function* () { + if (isWindowsPlatform()) { + return psTreeWindows(); + } + const [commands, withArgs] = yield Promise.all([ + runCommand('ps', ['-A', '-o', 'ppid,pid,comm']).toPromise(), + runCommand('ps', ['-A', '-ww', '-o', 'pid,args']).toPromise()]); + + + return parsePsOutput(commands, withArgs); + });return function psTree() {return _ref9.apply(this, arguments);};})();let psTreeWindows = (() => {var _ref10 = (0, _asyncToGenerator.default)( + + function* () { + const stdout = yield runCommand('wmic.exe', [ + 'PROCESS', + 'GET', + 'ParentProcessId,ProcessId,Name']). + toPromise(); + return parsePsOutput(stdout); + });return function psTreeWindows() {return _ref10.apply(this, arguments);};})(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// Use `ps` to get memory usage for an array of process id's as a map. +let memoryUsagePerPid = exports.memoryUsagePerPid = (() => {var _ref11 = (0, _asyncToGenerator.default)(function* ( + pids) + { + const usage = new Map(); + if (pids.length >= 1) { + try { + const stdout = yield runCommand('ps', [ + '-p', + pids.join(','), + '-o', + 'pid=', + '-o', + 'rss=']). + toPromise(); + stdout.split('\n').forEach(function (line) { + const parts = line.trim().split(/\s+/); + if (parts.length === 2) { + const [pid, rss] = parts.map(function (x) {return parseInt(x, 10);}); + usage.set(pid, rss); + } + }); + } catch (err) { + // Ignore errors. + } + } + return usage; + });return function memoryUsagePerPid(_x3) {return _ref11.apply(this, arguments);};})(); + +/** + * Add no-op error handlers to the process's streams so that Node doesn't throw them. + */let _killProcess = (() => {var _ref12 = (0, _asyncToGenerator.default)( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + function* ( + proc, + killTree) + { + proc.wasKilled = true; + if (!killTree) { + proc.kill(); + return; + } + if (/^win/.test(process.platform)) { + yield killWindowsProcessTree(proc.pid); + } else { + yield killUnixProcessTree(proc); + } + });return function _killProcess(_x4, _x5) {return _ref12.apply(this, arguments);};})();let killUnixProcessTree = exports.killUnixProcessTree = (() => {var _ref13 = (0, _asyncToGenerator.default)( + + + + + + + + + + + + + + function* ( + proc) + { + const descendants = yield getDescendantsOfProcess(proc.pid); + // Kill the processes, starting with those of greatest depth. + for (const info of descendants.reverse()) { + killPid(info.pid); + } + });return function killUnixProcessTree(_x6) {return _ref13.apply(this, arguments);};})();exports.runCommand = runCommand;exports.observeProcess = observeProcess;exports.runCommandDetailed = runCommandDetailed;exports.observeProcessRaw = observeProcessRaw;exports.spawn = spawn;exports.fork = fork;exports.getOutputStream = getOutputStream;exports.scriptifyCommand = scriptifyCommand;exports.killProcess = killProcess;exports.killPid = killPid;exports.exitEventToMessage = exitEventToMessage;exports.parsePsOutput = parsePsOutput;exports.preventStreamsFromThrowing = preventStreamsFromThrowing;exports.logStreamErrors = logStreamErrors;var _child_process = _interopRequireDefault(require('child_process'));var _idx;function _load_idx() {return _idx = _interopRequireDefault(require('idx'));}var _log4js;function _load_log4js() {return _log4js = require('log4js');}var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _util = _interopRequireDefault(require('util'));var _UniversalDisposable;function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('./UniversalDisposable'));}var _nuclideUri;function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('./nuclideUri'));}var _performanceNow;function _load_performanceNow() {return _performanceNow = _interopRequireDefault(require('./performanceNow'));}var _collection;function _load_collection() {return _collection = require('./collection');}var _event;function _load_event() {return _event = require('./event');}var _stream;function _load_stream() {return _stream = require('./stream');}var _observable;function _load_observable() {return _observable = require('./observable');}var _string;function _load_string() {return _string = require('./string');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}const LOG_CATEGORY = exports.LOG_CATEGORY = 'nuclide-commons/process'; /** + * 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. + * + * + * @format + */ // // __ __ __ __ ___ __ __ __ // |__) |__) / \ / ` |__ /__` /__` | /__` // | | \ \__/ \__, |___ .__/ .__/ .\__/ .__/ @@ -47,201 +1137,99 @@ // operators accidentally. // // [RxJS]: http://reactivex.io/rxjs/ - -import child_process from 'child_process'; -import idx from 'idx'; -import {getLogger} from 'log4js'; -import invariant from 'assert'; -import {Observable} from 'rxjs'; -import util from 'util'; - -import UniversalDisposable from './UniversalDisposable'; -import nuclideUri from './nuclideUri'; -import performanceNow from './performanceNow'; -import {MultiMap} from './collection'; -import {observableFromSubscribeFunction} from './event'; -import {observeStream} from './stream'; -import {splitStream, takeWhileInclusive} from './observable'; -import {shellQuote} from './string'; - -export const LOG_CATEGORY = 'nuclide-commons/process'; - -const logger = getLogger(LOG_CATEGORY); - -/** - * Run a command, accumulate the output. Errors are surfaced as stream errors and unsubscribing will - * kill the process. In addition to the options accepted by Node's [`child_process.spawn()`][1] - * function, `runCommand()` also accepts the following: - * - * - `input` {string | Observable} Text to write to the new process's stdin. - * - `killTreeWhenDone` {boolean} `false` by default. If you pass `true`, unsubscribing from the - * observable will kill not only this process but also its descendants. - * - `isExitError` {function} Determines whether a ProcessExitError should be raised based on the - * exit message. By default, this is a function that returns `true` if the exit code is non-zero. - * - `maxBuffer` {number} The maximum amount of stdout and stderror to accumulate. If the process - * produces more of either, a MaxBufferExceededError will be emitted. - * - `timeout` {number} The number of milliseconds to wait before killing the process and emitting - * an error. This is mostly provided for backwards compatibility, as you can get the same result - * by using the `.timeout()` operator on the returned observable. - * - * The observable returned by this function can error with any of the following: - * - * - [Node System Errors][2] Represented as augmented `Error` objects, these errors include things - * like `ENOENT`. - * - `ProcessExitError` Indicate that the process has ended cleanly, but with an unsuccessful exit - * code. Whether a `ProcessExitError` is thrown is determined by the `isExitError` option. This - * error includes the exit code as well as accumulated stdout and stderr. See its definition for - * more information. - * - `MaxBufferExceededError` Thrown if either the stdout or stderr exceeds the value specified by - * the `maxBuffer` option. - * - `ProcessTimeoutError` Thrown if the process doesn't complete within the time specified by the - * `timeout` option. - * - * Example: - * - * ```js - * const subscription = runCommand('ps', ['-e', '-o', 'pid,comm']) - * .map(stdout => { - * return stdout.split('\n') - * .slice(1) - * .map(line => { - * const words = line.trim().split(' '); - * return { - * pid: words[0], - * command: words.slice(1).join(' '), - * }; - * }) - * .sort((p1, p2) => p2.pid - p1.pid); - * }) - * .subscribe(processes => { - * console.log(`The process with the highest pid is ${processes[0].command}`); - * }); - * ``` - * - * [1]: https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options - * [2]: https://nodejs.org/api/errors.html#errors_class_system_error - */ -export function runCommand( - command: string, - args?: Array = [], - options?: ObserveProcessOptions = {}, - rest: void, -): Observable { - return runCommandDetailed(command, args, options).map(event => event.stdout); -} - -/** - * Returns an observable that spawns a process and emits events on stdout, stderr and exit. Output - * is buffered by line. Unsubscribing before the observable completes will kill the process. This - * function accepts the same options as `runCommand()`, and throws the same errors. - * - * Besides emitting multiple events, another difference with `runCommand()` is the ProcessExitErrors - * thrown by `observeProcess()`. Whereas ProcessExitErrors thrown by `runCommand()` contain the - * entirety of stdout and stderr, those thrown by `observeProcess()` contain a truncated amount of - * stderr and no stdout. This is because `observeProcess()` is usually used with long-running - * processes that may continue to produce output for a long while. The abbreviated stderr is - * included to help with debugging. - * - * Example: - * - * ```js - * const filesToTail: Observable = f(); - * const subscription = filesToTail - * // `switchMap()` means only one file will be tailed at a time. - * .switchMap(path => observeProcess('tail', ['-f', path])) - * .filter(event => event.kind === 'stdout') - * .map(event => event.data) - * .subscribe(line => { - * console.log(line); - * }); - * ``` - */ -export function observeProcess( - command: string, - args?: Array, - options?: ObserveProcessOptions, -): Observable { - return spawn(command, args, options).flatMap(proc => - getOutputStream(proc, options), - ); -} - -export type DetailedProcessResult = { - stdout: string, - stderr: string, - exitCode: ?number, -}; - -/** - * Identical to `runCommand()`, but instead of only emitting the accumulated stdout, the returned - * observable emits an object containing the accumulated stdout, the accumulated stderr, and the - * exit code. - * - * In general, you should prefer `runCommand()`, however, this function is useful for when stderr is - * needed even if the process exits successfully. - */ -export function runCommandDetailed( - command: string, - args?: Array = [], - options?: ObserveProcessOptions = {}, - rest: void, -): Observable { - const maxBuffer = idx(options, _ => _.maxBuffer) || DEFAULT_MAX_BUFFER; - return observeProcess(command, args, {...options, maxBuffer}) - .catch(error => { - // Catch ProcessExitErrors so that we can add stdout to them. - if (error instanceof ProcessExitError) { - return Observable.of({kind: 'process-exit-error', error}); - } - throw error; - }) - .reduce( - (acc, event) => { - switch (event.kind) { - case 'stdout': - return {...acc, stdout: acc.stdout + event.data}; - case 'stderr': - return {...acc, stderr: acc.stderr + event.data}; - case 'exit': - return {...acc, exitCode: event.exitCode}; - case 'process-exit-error': - const {error} = event; - throw new ProcessExitError( - error.exitCode, - error.signal, - error.process, - acc.stderr, - acc.stdout, - ); - default: - (event.kind: empty); - throw new Error(`Invalid event kind: ${event.kind}`); - } - }, - {stdout: '', stderr: '', exitCode: null}, - ); -} - -/** - * Identical to `observeProcess()`, but doesn't buffer by line. - */ -export function observeProcessRaw( - command: string, - args?: Array, - options?: ObserveProcessOptions, -): Observable { - return spawn(command, args, options).flatMap(proc => - getOutputStream(proc, {...options, splitByLines: false}), - ); -} - -// +const logger = (0, (_log4js || _load_log4js()).getLogger)(LOG_CATEGORY); /** + * Run a command, accumulate the output. Errors are surfaced as stream errors and unsubscribing will + * kill the process. In addition to the options accepted by Node's [`child_process.spawn()`][1] + * function, `runCommand()` also accepts the following: + * + * - `input` {string | Observable} Text to write to the new process's stdin. + * - `killTreeWhenDone` {boolean} `false` by default. If you pass `true`, unsubscribing from the + * observable will kill not only this process but also its descendants. + * - `isExitError` {function} Determines whether a ProcessExitError should be raised based on the + * exit message. By default, this is a function that returns `true` if the exit code is non-zero. + * - `maxBuffer` {number} The maximum amount of stdout and stderror to accumulate. If the process + * produces more of either, a MaxBufferExceededError will be emitted. + * - `timeout` {number} The number of milliseconds to wait before killing the process and emitting + * an error. This is mostly provided for backwards compatibility, as you can get the same result + * by using the `.timeout()` operator on the returned observable. + * + * The observable returned by this function can error with any of the following: + * + * - [Node System Errors][2] Represented as augmented `Error` objects, these errors include things + * like `ENOENT`. + * - `ProcessExitError` Indicate that the process has ended cleanly, but with an unsuccessful exit + * code. Whether a `ProcessExitError` is thrown is determined by the `isExitError` option. This + * error includes the exit code as well as accumulated stdout and stderr. See its definition for + * more information. + * - `MaxBufferExceededError` Thrown if either the stdout or stderr exceeds the value specified by + * the `maxBuffer` option. + * - `ProcessTimeoutError` Thrown if the process doesn't complete within the time specified by the + * `timeout` option. + * + * Example: + * + * ```js + * const subscription = runCommand('ps', ['-e', '-o', 'pid,comm']) + * .map(stdout => { + * return stdout.split('\n') + * .slice(1) + * .map(line => { + * const words = line.trim().split(' '); + * return { + * pid: words[0], + * command: words.slice(1).join(' '), + * }; + * }) + * .sort((p1, p2) => p2.pid - p1.pid); + * }) + * .subscribe(processes => { + * console.log(`The process with the highest pid is ${processes[0].command}`); + * }); + * ``` + * + * [1]: https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options + * [2]: https://nodejs.org/api/errors.html#errors_class_system_error + */function runCommand(command, args = [], options = {}, rest) {return runCommandDetailed(command, args, options).map(event => event.stdout);} /** + * Returns an observable that spawns a process and emits events on stdout, stderr and exit. Output + * is buffered by line. Unsubscribing before the observable completes will kill the process. This + * function accepts the same options as `runCommand()`, and throws the same errors. + * + * Besides emitting multiple events, another difference with `runCommand()` is the ProcessExitErrors + * thrown by `observeProcess()`. Whereas ProcessExitErrors thrown by `runCommand()` contain the + * entirety of stdout and stderr, those thrown by `observeProcess()` contain a truncated amount of + * stderr and no stdout. This is because `observeProcess()` is usually used with long-running + * processes that may continue to produce output for a long while. The abbreviated stderr is + * included to help with debugging. + * + * Example: + * + * ```js + * const filesToTail: Observable = f(); + * const subscription = filesToTail + * // `switchMap()` means only one file will be tailed at a time. + * .switchMap(path => observeProcess('tail', ['-f', path])) + * .filter(event => event.kind === 'stdout') + * .map(event => event.data) + * .subscribe(line => { + * console.log(line); + * }); + * ``` + */function observeProcess(command, args, options) {return spawn(command, args, options).flatMap(proc => getOutputStream(proc, options));} /** + * Identical to `runCommand()`, but instead of only emitting the accumulated stdout, the returned + * observable emits an object containing the accumulated stdout, the accumulated stderr, and the + * exit code. + * + * In general, you should prefer `runCommand()`, however, this function is useful for when stderr is + * needed even if the process exits successfully. + */function runCommandDetailed(command, args = [], options = {}, rest) {var _ref;const maxBuffer = ((_ref = options) != null ? _ref.maxBuffer : _ref) || DEFAULT_MAX_BUFFER;return observeProcess(command, args, Object.assign({}, options, { maxBuffer })).catch(error => {// Catch ProcessExitErrors so that we can add stdout to them. + if (error instanceof ProcessExitError) {return _rxjsBundlesRxMinJs.Observable.of({ kind: 'process-exit-error', error });}throw error;}).reduce((acc, event) => {switch (event.kind) {case 'stdout':return Object.assign({}, acc, { stdout: acc.stdout + event.data });case 'stderr':return Object.assign({}, acc, { stderr: acc.stderr + event.data });case 'exit':return Object.assign({}, acc, { exitCode: event.exitCode });case 'process-exit-error':const { error } = event;throw new ProcessExitError(error.exitCode, error.signal, error.process, acc.stderr, acc.stdout);default:event.kind;throw new Error(`Invalid event kind: ${event.kind}`);}}, { stdout: '', stderr: '', exitCode: null });} /** + * Identical to `observeProcess()`, but doesn't buffer by line. + */function observeProcessRaw(command, args, options) {return spawn(command, args, options).flatMap(proc => getOutputStream(proc, Object.assign({}, options, { splitByLines: false })));} // // # Lower-level APIs // // The following functions are used to create the higher-level APIs above. It's rare that you'll // need to use them by themselves. // - /** * Creates an observable that spawns a process and emits it. Like with `runCommand()` and * `observeProcess()`, if you unsubscribe from the returned observable, the process will be killed @@ -267,117 +1255,30 @@ export function observeProcessRaw( * // These events are the same as those emitted by `observeProcess()`. * }); * ``` - */ -export function spawn( - command: string, - args?: Array, - options?: SpawnProcessOptions, -): Observable { - return createProcessStream('spawn', command, args, options); -} - -/** - * Identical to `spawn()` (above), but uses `child_process.fork()` to create the process. - */ -export function fork( - modulePath: string, - args?: Array, - options?: ForkProcessOptions, -): Observable { - return createProcessStream('fork', modulePath, args, options); -} - -/** - * Creates a stream of sensibly-ordered stdout, stdin, and exit messages from a process. Generally, - * you shouldn't use this function and should instead use `observeProcess()` (which makes use of - * this for you). - * - * IMPORTANT: If you must use this function, it's very important that the process you give it was - * just synchronously created. Otherwise, you can end up missing messages. - * - * This function intentionally does not close the process when you unsubscribe. It's usually used in - * conjunction with `spawn()` which does that already. - */ -export function getOutputStream( - proc: child_process$ChildProcess, - options?: GetOutputStreamOptions, - rest: void, -): Observable { - const chunk = - idx(options, _ => _.splitByLines) === false ? x => x : splitStream; - const maxBuffer = idx(options, _ => _.maxBuffer); - const isExitError = idx(options, _ => _.isExitError) || isExitErrorDefault; - const exitErrorBufferSize = idx(options, _ => _.exitErrorBufferSize) || 2000; - return Observable.defer(() => { - const stdoutEvents = chunk( - limitBufferSize(observeStream(proc.stdout), maxBuffer, 'stdout'), - ).map(data => ({kind: 'stdout', data})); - const stderrEvents = chunk( - limitBufferSize(observeStream(proc.stderr), maxBuffer, 'stderr'), - ) - .map(data => ({kind: 'stderr', data})) - .share(); - - // Accumulate the first `exitErrorBufferSize` bytes of stderr so that we can give feedback about + */function spawn(command, args, options) {return createProcessStream('spawn', command, args, options);} /** + * Identical to `spawn()` (above), but uses `child_process.fork()` to create the process. + */function fork(modulePath, args, options) {return createProcessStream('fork', modulePath, args, options);} /** + * Creates a stream of sensibly-ordered stdout, stdin, and exit messages from a process. Generally, + * you shouldn't use this function and should instead use `observeProcess()` (which makes use of + * this for you). + * + * IMPORTANT: If you must use this function, it's very important that the process you give it was + * just synchronously created. Otherwise, you can end up missing messages. + * + * This function intentionally does not close the process when you unsubscribe. It's usually used in + * conjunction with `spawn()` which does that already. + */function getOutputStream(proc, options, rest) {var _ref2, _ref3, _ref4, _ref5;const chunk = ((_ref2 = options) != null ? _ref2.splitByLines : _ref2) === false ? x => x : (_observable || _load_observable()).splitStream;const maxBuffer = (_ref3 = options) != null ? _ref3.maxBuffer : _ref3;const isExitError = ((_ref4 = options) != null ? _ref4.isExitError : _ref4) || isExitErrorDefault;const exitErrorBufferSize = ((_ref5 = options) != null ? _ref5.exitErrorBufferSize : _ref5) || 2000;return _rxjsBundlesRxMinJs.Observable.defer(() => {const stdoutEvents = chunk(limitBufferSize((0, (_stream || _load_stream()).observeStream)(proc.stdout), maxBuffer, 'stdout')).map(data => ({ kind: 'stdout', data }));const stderrEvents = chunk(limitBufferSize((0, (_stream || _load_stream()).observeStream)(proc.stderr), maxBuffer, 'stderr')).map(data => ({ kind: 'stderr', data })).share(); // Accumulate the first `exitErrorBufferSize` bytes of stderr so that we can give feedback about // about exit errors (then stop so we don't fill up memory with it). - const accumulatedStderr = stderrEvents - .scan( - (acc, event) => (acc + event.data).slice(0, exitErrorBufferSize), - '', - ) - .startWith('') - .let(takeWhileInclusive(acc => acc.length < exitErrorBufferSize)); - - // We need to start listening for the exit event immediately, but defer emitting it until the + const accumulatedStderr = stderrEvents.scan((acc, event) => (acc + event.data).slice(0, exitErrorBufferSize), '').startWith('').let((0, (_observable || _load_observable()).takeWhileInclusive)(acc => acc.length < exitErrorBufferSize)); // We need to start listening for the exit event immediately, but defer emitting it until the // (buffered) output streams end. - const closeEvents = Observable.fromEvent( - proc, - // We listen to the "close" event instead of "exit" because we want to get all of the stdout - // and stderr. - 'close', - (exitCode: ?number, signal: ?string) => ({ - kind: 'exit', - exitCode, - signal, - }), - ) - .filter(isRealExit) - .take(1) - .withLatestFrom(accumulatedStderr) - .map(([event, stderr]) => { - if (isExitError(event)) { - throw new ProcessExitError( - event.exitCode, - event.signal, - proc, - stderr, - ); - } - return event; - }) - .publishReplay(); - const exitSub = closeEvents.connect(); - - return Observable.merge(stdoutEvents, stderrEvents) - .concat(closeEvents) - .let( - takeWhileInclusive( - event => event.kind !== 'error' && event.kind !== 'exit', - ), - ) - .finally(() => { - exitSub.unsubscribe(); - }); - }); -} - -// + const closeEvents = _rxjsBundlesRxMinJs.Observable.fromEvent(proc, // We listen to the "close" event instead of "exit" because we want to get all of the stdout + // and stderr. + 'close', (exitCode, signal) => ({ kind: 'exit', exitCode, signal })).filter(isRealExit).take(1).withLatestFrom(accumulatedStderr).map(([event, stderr]) => {if (isExitError(event)) {throw new ProcessExitError(event.exitCode, event.signal, proc, stderr);}return event;}).publishReplay();const exitSub = closeEvents.connect();return _rxjsBundlesRxMinJs.Observable.merge(stdoutEvents, stderrEvents).concat(closeEvents).let((0, (_observable || _load_observable()).takeWhileInclusive)(event => event.kind !== 'error' && event.kind !== 'exit')).finally(() => {exitSub.unsubscribe();});});} // // # Miscellaneous Utilities // // The following utilities don't spawn processes or necessarily use observables. Instead, they're // used to format arguments to the above functions or for acting on already-spawned processes. // - /** * Takes the arguments that you would normally pass to `spawn()` and returns an array of new * arguments to use to run the command under `script`. @@ -389,367 +1290,33 @@ export function getOutputStream( * ``` * * See also `nicifyCommand()` which does a similar thing but for `nice`. - */ -export function scriptifyCommand( - command: string, - args?: Array = [], - options: T, -): [string, Array, T] { - if (process.platform === 'darwin') { - // On OS X, script takes the program to run and its arguments as varargs at the end. - return ['script', ['-q', '/dev/null', command].concat(args), options]; - } else { - // On Linux, script takes the command to run as the -c parameter so we have to combine all of + */function scriptifyCommand(command, args = [], options) {if (process.platform === 'darwin') {// On OS X, script takes the program to run and its arguments as varargs at the end. + return ['script', ['-q', '/dev/null', command].concat(args), options];} else {// On Linux, script takes the command to run as the -c parameter so we have to combine all of // the arguments into a single string. - const joined = shellQuote([command, ...args]); - // flowlint-next-line sketchy-null-mixed:off - const opts = options || {}; - // flowlint-next-line sketchy-null-mixed:off - const env = opts.env || {}; - return [ - 'script', - ['-q', '/dev/null', '-c', joined], - // `script` will use `SHELL`, but shells have different behaviors with regard to escaping. To - // make sure that out escaping is correct, we need to force a particular shell. - {...opts, env: {...env, SHELL: '/bin/bash'}}, - ]; - } -} - -/** - * Kills a process and, optionally, its descendants. - */ -export function killProcess( - proc: child_process$ChildProcess, - killTree: boolean, -): void { - _killProcess(proc, killTree).then( - () => {}, - error => { - logger.error(`Killing process ${proc.pid} failed`, error); - }, - ); -} - -/** - * Kill the process with the provided pid. - */ -export function killPid(pid: number): void { - try { - process.kill(pid); - } catch (err) { - if (err.code !== 'ESRCH') { - throw err; - } - } -} - -// If provided, read the original environment from NUCLIDE_ORIGINAL_ENV. + const joined = (0, (_string || _load_string()).shellQuote)([command, ...args]); // flowlint-next-line sketchy-null-mixed:off + const opts = options || {}; // flowlint-next-line sketchy-null-mixed:off + const env = opts.env || {};return ['script', ['-q', '/dev/null', '-c', joined], // `script` will use `SHELL`, but shells have different behaviors with regard to escaping. To + // make sure that out escaping is correct, we need to force a particular shell. + Object.assign({}, opts, { env: Object.assign({}, env, { SHELL: '/bin/bash' }) })];}} /** + * Kills a process and, optionally, its descendants. + */function killProcess(proc, killTree) {_killProcess(proc, killTree).then(() => {}, error => {logger.error(`Killing process ${proc.pid} failed`, error);});} /** + * Kill the process with the provided pid. + */function killPid(pid) {try {process.kill(pid);} catch (err) {if (err.code !== 'ESRCH') {throw err;}}} // If provided, read the original environment from NUCLIDE_ORIGINAL_ENV. // This should contain the base64-encoded output of `env -0`. -let cachedOriginalEnvironment = null; -export async function getOriginalEnvironment(): Promise { - await new Promise(resolve => { - whenShellEnvironmentLoaded(resolve); - }); - if (cachedOriginalEnvironment != null) { - return cachedOriginalEnvironment; - } - - const {NUCLIDE_ORIGINAL_ENV} = process.env; - if (NUCLIDE_ORIGINAL_ENV != null && NUCLIDE_ORIGINAL_ENV.trim() !== '') { - const envString = new Buffer(NUCLIDE_ORIGINAL_ENV, 'base64').toString(); - cachedOriginalEnvironment = {}; - for (const envVar of envString.split('\0')) { - // envVar should look like A=value_of_A - const equalIndex = envVar.indexOf('='); - if (equalIndex !== -1) { - cachedOriginalEnvironment[ - envVar.substring(0, equalIndex) - ] = envVar.substring(equalIndex + 1); - } - } - // Guard against invalid original environments. - if (!Object.keys(cachedOriginalEnvironment).length) { - cachedOriginalEnvironment = process.env; - } - } else { - cachedOriginalEnvironment = process.env; - } - return cachedOriginalEnvironment; -} - -/** - * Returns a string suitable for including in displayed error messages. - */ -export function exitEventToMessage(event: { - exitCode: ?number, - signal: ?string, -}): string { - if (event.exitCode != null) { - return `exit code ${event.exitCode}`; - } else { - invariant(event.signal != null); - return `signal ${event.signal}`; - } -} - -export async function getChildrenOfProcess( - processId: number, -): Promise> { - const processes = await psTree(); - - return processes.filter(processInfo => processInfo.parentPid === processId); -} - -/** - * Get a list of descendants, sorted by increasing depth (including the one with the provided pid). - */ -async function getDescendantsOfProcess( - pid: number, -): Promise> { - const processes = await psTree(); - let rootProcessInfo; - const pidToChildren = new MultiMap(); - processes.forEach(info => { - if (info.pid === pid) { - rootProcessInfo = info; - } - pidToChildren.add(info.parentPid, info); - }); - const descendants = rootProcessInfo == null ? [] : [rootProcessInfo]; - // Walk through the array, adding the children of the current element to the end. This - // breadth-first traversal means that the elements will be sorted by depth. - for (let i = 0; i < descendants.length; i++) { - const info = descendants[i]; - const children = pidToChildren.get(info.pid); - descendants.push(...Array.from(children)); - } - return descendants; -} - -export async function psTree(): Promise> { - if (isWindowsPlatform()) { - return psTreeWindows(); - } - const [commands, withArgs] = await Promise.all([ - runCommand('ps', ['-A', '-o', 'ppid,pid,comm']).toPromise(), - runCommand('ps', ['-A', '-ww', '-o', 'pid,args']).toPromise(), - ]); - - return parsePsOutput(commands, withArgs); -} - -async function psTreeWindows(): Promise> { - const stdout = await runCommand('wmic.exe', [ - 'PROCESS', - 'GET', - 'ParentProcessId,ProcessId,Name', - ]).toPromise(); - return parsePsOutput(stdout); -} - -export function parsePsOutput( - psOutput: string, - argsOutput: ?string, -): Array { - // Remove the first header line. - const lines = psOutput - .trim() - .split(/\n|\r\n/) - .slice(1); - - let withArgs = new Map(); - if (argsOutput != null) { - withArgs = new Map( - argsOutput - .trim() - .split(/\n|\r\n/) - .slice(1) - .map(line => { - const columns = line.trim().split(/\s+/); - const pid = parseInt(columns[0], 10); - const command = columns.slice(1).join(' '); - return [pid, command]; - }), - ); - } - - return lines.map(line => { - const columns = line.trim().split(/\s+/); - const [parentPid, pidStr] = columns; - const pid = parseInt(pidStr, 10); - const command = columns.slice(2).join(' '); - const commandWithArgs = withArgs.get(pid); - - return { - command, - parentPid: parseInt(parentPid, 10), - pid, - commandWithArgs: commandWithArgs == null ? command : commandWithArgs, - }; - }); -} - -// Use `ps` to get memory usage for an array of process id's as a map. -export async function memoryUsagePerPid( - pids: Array, -): Promise> { - const usage = new Map(); - if (pids.length >= 1) { - try { - const stdout = await runCommand('ps', [ - '-p', - pids.join(','), - '-o', - 'pid=', - '-o', - 'rss=', - ]).toPromise(); - stdout.split('\n').forEach(line => { - const parts = line.trim().split(/\s+/); - if (parts.length === 2) { - const [pid, rss] = parts.map(x => parseInt(x, 10)); - usage.set(pid, rss); - } - }); - } catch (err) { - // Ignore errors. - } - } - return usage; -} - -/** - * Add no-op error handlers to the process's streams so that Node doesn't throw them. - */ -export function preventStreamsFromThrowing( - proc: child_process$ChildProcess, -): IDisposable { - return new UniversalDisposable(getStreamErrorEvents(proc).subscribe()); -} - -/** - * Log errors from a process's streams. This function returns an `rxjs$ISubscription` so that it - * can easily be used with `Observable.using()`. - */ -export function logStreamErrors( - proc: child_process$ChildProcess, - command: string, - args: Array, - options?: Object, -): IDisposable & rxjs$ISubscription { - return new UniversalDisposable( - getStreamErrorEvents(proc) - .do(([err, streamName]) => { - logger.error( - `stream error on stream ${streamName} with command:`, - command, - args, - options, - 'error:', - err, - ); - }) - .subscribe(), - ); -} - -// +let cachedOriginalEnvironment = null;function exitEventToMessage(event) {if (event.exitCode != null) {return `exit code ${event.exitCode}`;} else {if (!(event.signal != null)) {throw new Error('Invariant violation: "event.signal != null"');}return `signal ${event.signal}`;}}function parsePsOutput(psOutput, argsOutput) {// Remove the first header line. + const lines = psOutput.trim().split(/\n|\r\n/).slice(1);let withArgs = new Map();if (argsOutput != null) {withArgs = new Map(argsOutput.trim().split(/\n|\r\n/).slice(1).map(line => {const columns = line.trim().split(/\s+/);const pid = parseInt(columns[0], 10);const command = columns.slice(1).join(' ');return [pid, command];}));}return lines.map(line => {const columns = line.trim().split(/\s+/);const [parentPid, pidStr] = columns;const pid = parseInt(pidStr, 10);const command = columns.slice(2).join(' ');const commandWithArgs = withArgs.get(pid);return { command, parentPid: parseInt(parentPid, 10), pid, commandWithArgs: commandWithArgs == null ? command : commandWithArgs };});}function preventStreamsFromThrowing(proc) {return new (_UniversalDisposable || _load_UniversalDisposable()).default(getStreamErrorEvents(proc).subscribe());} /** + * Log errors from a process's streams. This function returns an `rxjs$ISubscription` so that it + * can easily be used with `Observable.using()`. + */function logStreamErrors(proc, command, args, options) {return new (_UniversalDisposable || _load_UniversalDisposable()).default(getStreamErrorEvents(proc).do(([err, streamName]) => {logger.error(`stream error on stream ${streamName} with command:`, command, args, options, 'error:', err);}).subscribe());} // // Types // - // Exactly one of exitCode and signal will be non-null. // Killing a process will result in a null exitCode but a non-null signal. -export type ProcessExitMessage = { - kind: 'exit', - exitCode: ?number, - signal: ?string, -}; - -export type ProcessMessage = - | { - kind: 'stdout', - data: string, - } - | { - kind: 'stderr', - data: string, - } - | ProcessExitMessage; - // In older versions of process.js, errors were emitted as messages instead of errors. This type // exists to support the transition, but no new usages should be added. -export type LegacyProcessMessage = - | ProcessMessage - | {kind: 'error', error: Object}; - -export type ProcessInfo = { - parentPid: number, - pid: number, - command: string, - commandWithArgs: string, -}; - -export type Level = 'info' | 'log' | 'warning' | 'error' | 'debug' | 'success'; -export type Message = {text: string, level: Level}; - -export type MessageEvent = { - type: 'message', - message: Message, -}; - -export type ProgressEvent = { - type: 'progress', - progress: ?number, -}; - -export type ResultEvent = { - type: 'result', - result: mixed, -}; - -export type StatusEvent = { - type: 'status', - status: ?string, -}; - -export type TaskEvent = - | MessageEvent - | ProgressEvent - | ResultEvent - | StatusEvent; - -type CreateProcessStreamOptions = ( - | child_process$spawnOpts - | child_process$forkOpts -) & { - killTreeWhenDone?: ?boolean, - timeout?: ?number, - input?: ?(string | Observable), - dontLogInNuclide?: ?boolean, -}; - -type GetOutputStreamOptions = { - splitByLines?: ?boolean, - maxBuffer?: ?number, - exitErrorBufferSize?: ?number, - isExitError?: ?(event: ProcessExitMessage) => boolean, -}; - -export type ObserveProcessOptions = SpawnProcessOptions & - GetOutputStreamOptions; - -export type SpawnProcessOptions = child_process$spawnOpts & - CreateProcessStreamOptions; -export type ForkProcessOptions = child_process$forkOpts & - CreateProcessStreamOptions; - -export type ProcessError = ProcessSystemError | ProcessExitError; - // // Errors // - /** * An error thrown by process utils when the process exits with an error code. This type has all the * properties of ProcessExitMessage (except "kind"). @@ -758,385 +1325,64 @@ export type ProcessError = ProcessSystemError | ProcessExitError; * output-accumulating functions (`runCommand()`, `runCommandDetailed()`). For others, like * `observeProcess()`, it will be truncated. Similarly, `stdout` will only be populated when the * error is thrown by output-accumulating functions. For others, it will always be `null`. - */ -export class ProcessExitError extends Error { - exitCode: ?number; - signal: ?string; - stderr: string; - stdout: ?string; - command: string; - args: Array; - process: child_process$ChildProcess; - - constructor( - exitCode: ?number, - signal: ?string, - proc: child_process$ChildProcess, - stderr: string, - stdout?: string, - ) { - // $FlowIssue: This isn't typed in the Flow node type defs - const {spawnargs} = proc; - const argsAndCommand = - spawnargs[0] === process.execPath ? spawnargs.slice(1) : spawnargs; - const [command, ...args] = argsAndCommand; - super( - `"${command}" failed with ${exitEventToMessage({ - exitCode, - signal, - })}\n\n${stderr}\n\n${argsAndCommand.join(' ')}`, - ); - this.name = 'ProcessExitError'; - this.exitCode = exitCode; - this.signal = signal; - this.stderr = stderr; - this.stdout = stdout; - this.command = command; - this.args = args; - this.process = proc; - } -} - -/** - * Process system errors are just augmented Error objects. We wrap the errors and expose the process - * since our utilities throw the errors before returning the process. - */ -export class ProcessSystemError extends Error { - errno: number | string; - code: string; - path: ?string; - syscall: ?string; - process: child_process$ChildProcess; - - constructor(err: any, proc: child_process$ChildProcess) { - super(err.message); - this.name = 'ProcessSystemError'; - this.errno = err.errno; - this.code = err.code; - this.path = err.path; - this.syscall = err.syscall; - this.process = proc; - } -} - -export class MaxBufferExceededError extends Error { - constructor(streamName: string) { - super(`${streamName} maxBuffer exceeded`); - this.name = 'MaxBufferExceededError'; - } -} - -export class ProcessTimeoutError extends Error { - constructor(timeout: number, proc: child_process$ChildProcess) { - // $FlowIssue: This isn't typed in the Flow node type defs - const {spawnargs} = proc; - const commandName = - spawnargs[0] === process.execPath ? spawnargs[1] : spawnargs[0]; - super(`"${commandName}" timed out after ${timeout}ms`); - this.name = 'ProcessTimeoutError'; - } -} - -// + */class ProcessExitError extends Error {constructor(exitCode, signal, proc, stderr, stdout) {// $FlowIssue: This isn't typed in the Flow node type defs + const { spawnargs } = proc;const argsAndCommand = spawnargs[0] === process.execPath ? spawnargs.slice(1) : spawnargs;const [command, ...args] = argsAndCommand;super(`"${command}" failed with ${exitEventToMessage({ exitCode, signal })}\n\n${stderr}\n\n${argsAndCommand.join(' ')}`);this.name = 'ProcessExitError';this.exitCode = exitCode;this.signal = signal;this.stderr = stderr;this.stdout = stdout;this.command = command;this.args = args;this.process = proc;}}exports.ProcessExitError = ProcessExitError; /** + * Process system errors are just augmented Error objects. We wrap the errors and expose the process + * since our utilities throw the errors before returning the process. + */class ProcessSystemError extends Error {constructor(err, proc) {super(err.message);this.name = 'ProcessSystemError';this.errno = err.errno;this.code = err.code;this.path = err.path;this.syscall = err.syscall;this.process = proc;}}exports.ProcessSystemError = ProcessSystemError;class MaxBufferExceededError extends Error {constructor(streamName) {super(`${streamName} maxBuffer exceeded`);this.name = 'MaxBufferExceededError';}}exports.MaxBufferExceededError = MaxBufferExceededError;class ProcessTimeoutError extends Error {constructor(timeout, proc) {// $FlowIssue: This isn't typed in the Flow node type defs + const { spawnargs } = proc;const commandName = spawnargs[0] === process.execPath ? spawnargs[1] : spawnargs[0];super(`"${commandName}" timed out after ${timeout}ms`);this.name = 'ProcessTimeoutError';}}exports.ProcessTimeoutError = ProcessTimeoutError; // // Internal Stuff // // Pay no attention! This is just stuff that's used internally to implement the good stuff. // - // Node crashes if we allow buffers that are too large. -const DEFAULT_MAX_BUFFER = 100 * 1024 * 1024; - -const MAX_LOGGED_CALLS = 100; -const NUM_PRESERVED_HISTORY_CALLS = 50; - -const noopDisposable = {dispose: () => {}}; -const whenShellEnvironmentLoaded = - typeof atom !== 'undefined' && !atom.inSpecMode() - ? atom.whenShellEnvironmentLoaded.bind(atom) - : cb => { - cb(); - return noopDisposable; - }; - -/** - * Log custom events to log4js so that we can easily hook into process events - * using a custom log4js appender (e.g. for analytics purposes). - */ -export class ProcessLoggingEvent { - command: string; - duration: number; - - constructor(command: string, duration: number) { - this.command = command; - this.duration = duration; - // log4js uses util.inspect to convert log arguments to strings. +const DEFAULT_MAX_BUFFER = 100 * 1024 * 1024;const MAX_LOGGED_CALLS = 100;const NUM_PRESERVED_HISTORY_CALLS = 50;const noopDisposable = { dispose: () => {} };const whenShellEnvironmentLoaded = typeof atom !== 'undefined' && !atom.inSpecMode() ? atom.whenShellEnvironmentLoaded.bind(atom) : cb => {cb();return noopDisposable;}; /** + * Log custom events to log4js so that we can easily hook into process events + * using a custom log4js appender (e.g. for analytics purposes). + */class ProcessLoggingEvent {constructor(command, duration) {this.command = command;this.duration = duration; // log4js uses util.inspect to convert log arguments to strings. // Note: computed property methods aren't supported by Flow yet. - (this: any)[util.inspect.custom] = () => { - return `${this.duration}ms: ${this.command}`; - }; - } -} - -export const loggedCalls = []; -function logCall(duration: number, command: string, args: Array) { - // Trim the history once in a while, to avoid doing expensive array + this[_util.default.inspect.custom] = () => {return `${this.duration}ms: ${this.command}`;};}}exports.ProcessLoggingEvent = ProcessLoggingEvent;const loggedCalls = exports.loggedCalls = [];function logCall(duration, command, args) {// Trim the history once in a while, to avoid doing expensive array // manipulation all the time after we reached the end of the history - if (loggedCalls.length > MAX_LOGGED_CALLS) { - loggedCalls.splice(0, loggedCalls.length - NUM_PRESERVED_HISTORY_CALLS, { - command: '... history stripped ...', - duration: 0, - time: new Date(), - }); - } - - const fullCommand = shellQuote([command, ...args]); - loggedCalls.push({ - command: fullCommand, - duration, - time: new Date(), - }); - logger.info(new ProcessLoggingEvent(fullCommand, duration)); -} - -/** - * Creates an observable with the following properties: - * - * 1. It contains a process that's created using the provided factory when you subscribe. - * 2. It doesn't complete until the process exits (or errors). - * 3. The process is killed when you unsubscribe. - * - * This means that a single observable instance can be used to spawn multiple processes. Indeed, if - * you subscribe multiple times, multiple processes *will* be spawned. - * - * IMPORTANT: The exit event does NOT mean that all stdout and stderr events have been received. - */ -function createProcessStream( - type: 'spawn' | 'fork' = 'spawn', - commandOrModulePath: string, - args?: Array = [], - options?: CreateProcessStreamOptions = {}, -): Observable { - const inputOption = options.input; - let input; - if (inputOption != null) { - input = - typeof inputOption === 'string' - ? Observable.of(inputOption) - : inputOption; - } - - return observableFromSubscribeFunction(whenShellEnvironmentLoaded) - .take(1) - .switchMap(() => { - const {dontLogInNuclide, killTreeWhenDone, timeout} = options; - // flowlint-next-line sketchy-null-number:off - const enforceTimeout = timeout - ? x => - x.timeoutWith( - timeout, - Observable.throw(new ProcessTimeoutError(timeout, proc)), - ) - : x => x; - const proc = child_process[type]( - nuclideUri.expandHomeDir(commandOrModulePath), - args, - // $FlowFixMe: child_process$spawnOpts and child_process$forkOpts have incompatible stdio types. - {...options}, - ); - - // Don't let Node throw stream errors and crash the process. Note that we never dispose of - // this because stream errors can still occur after the user unsubscribes from our process - // observable. That's okay; when the streams close, the listeners will be removed. - preventStreamsFromThrowing(proc); - - // If we were to connect the error handler as part of the returned observable, unsubscribing - // would cause it to be removed. That would leave no attached error handler, so node would - // throw, triggering Atom's uncaught exception handler. - const errors = Observable.fromEvent(proc, 'error') - .flatMap(Observable.throw) - .publish(); - errors.connect(); - - const exitEvents = Observable.fromEvent( - proc, - 'exit', - (exitCode: ?number, signal: ?string) => ({ - kind: 'exit', - exitCode, - signal, - }), - ) - .filter(isRealExit) - .take(1); - - if (dontLogInNuclide !== true) { - // Log the completion of the process. Note that we intentionally don't merge this with the - // returned observable because we don't want to cancel the side-effect when the user - // unsubscribes or when the process exits ("close" events come after "exit" events). - const now = performanceNow(); - Observable.fromEvent(proc, 'close') - .do(() => { - logCall( - Math.round(performanceNow() - now), - commandOrModulePath, - args, - ); - }) - .subscribe(); - } - - let finished = false; - return enforceTimeout( - Observable.using( - // Log stream errors, but only for as long as you're subscribed to the process observable. - () => logStreamErrors(proc, commandOrModulePath, args, options), - () => - Observable.merge( - // Node [delays the emission of process errors][1] by a tick in order to give - // consumers a chance to subscribe to the error event. This means that our observable - // would normally emit the process and then, a tick later, error. However, it's more - // convenient to never emit the process if there was an error. Although observables - // don't require the error to be delayed at all, the underlying event emitter - // abstraction does, so we'll just roll with that and use `pid == null` as a signal - // that an error is forthcoming. - // - // [1]: https://github.com/nodejs/node/blob/v7.10.0/lib/internal/child_process.js#L301 - proc.pid == null ? Observable.empty() : Observable.of(proc), - Observable.never(), // Don't complete until we say so! - ), - ) - .merge( - // Write any input to stdin. This is just for the side-effect. We merge it here to - // ensure that writing to the stdin stream happens after our event listeners are added. - input == null - ? Observable.empty() - : input - .do({ - next: str => { - proc.stdin.write(str); - }, - complete: () => { - proc.stdin.end(); - }, - }) - .ignoreElements(), - ) - .takeUntil(errors) - .takeUntil(exitEvents) - .do({ - error: () => { - finished = true; - }, - complete: () => { - finished = true; - }, - }), - ) - .catch(err => { - // Since this utility errors *before* emitting the process, add the process to the error - // so that users can get whatever info they need off of it. - if (err instanceof Error && err.name === 'Error' && 'errno' in err) { - throw new ProcessSystemError(err, proc); - } - throw err; - }) - .finally(() => { - // flowlint-next-line sketchy-null-mixed:off - if (!proc.wasKilled && !finished) { - killProcess(proc, Boolean(killTreeWhenDone)); - } - }); - }); -} - -function isRealExit(event: {exitCode: ?number, signal: ?string}): boolean { - // An exit signal from SIGUSR1 doesn't actually exit the process, so skip that. - return event.signal !== 'SIGUSR1'; -} - -async function _killProcess( - proc: child_process$ChildProcess & {wasKilled?: boolean}, - killTree: boolean, -): Promise { - proc.wasKilled = true; - if (!killTree) { - proc.kill(); - return; - } - if (/^win/.test(process.platform)) { - await killWindowsProcessTree(proc.pid); - } else { - await killUnixProcessTree(proc); - } -} - -function killWindowsProcessTree(pid: number): Promise { - return new Promise((resolve, reject) => { - child_process.exec(`taskkill /pid ${pid} /T /F`, error => { - if (error == null) { - reject(error); - } else { - resolve(); - } - }); - }); -} - -export async function killUnixProcessTree( - proc: child_process$ChildProcess, -): Promise { - const descendants = await getDescendantsOfProcess(proc.pid); - // Kill the processes, starting with those of greatest depth. - for (const info of descendants.reverse()) { - killPid(info.pid); - } -} - -function isExitErrorDefault(exit: ProcessExitMessage): boolean { - return exit.exitCode !== 0; -} - -function isWindowsPlatform(): boolean { - return /^win/.test(process.platform); -} - -function limitBufferSize( - stream: Observable, - maxBuffer: ?number, - streamName: string, -): Observable { - if (maxBuffer == null) { - return stream; - } - return Observable.defer(() => { - let totalSize = 0; - return stream.do(data => { - totalSize += data.length; - if (totalSize > maxBuffer) { - throw new MaxBufferExceededError(streamName); - } - }); - }); -} - -/** - * Get an observable of error events for a process's streams. Note that these are represented as - * normal elements, not observable errors. - */ -function getStreamErrorEvents( - proc: child_process$ChildProcess, -): Observable<[Error, string]> { - const streams = [ - ['stdin', proc.stdin], - ['stdout', proc.stdout], - ['stderr', proc.stderr], - ]; - return Observable.merge( - ...streams.map( - ([name, stream]) => - stream == null - ? Observable.empty() - : Observable.fromEvent(stream, 'error').map(err => [err, name]), - ), - ); -} + if (loggedCalls.length > MAX_LOGGED_CALLS) {loggedCalls.splice(0, loggedCalls.length - NUM_PRESERVED_HISTORY_CALLS, { command: '... history stripped ...', duration: 0, time: new Date() });}const fullCommand = (0, (_string || _load_string()).shellQuote)([command, ...args]);loggedCalls.push({ command: fullCommand, duration, time: new Date() });logger.info(new ProcessLoggingEvent(fullCommand, duration));} /** + * Creates an observable with the following properties: + * + * 1. It contains a process that's created using the provided factory when you subscribe. + * 2. It doesn't complete until the process exits (or errors). + * 3. The process is killed when you unsubscribe. + * + * This means that a single observable instance can be used to spawn multiple processes. Indeed, if + * you subscribe multiple times, multiple processes *will* be spawned. + * + * IMPORTANT: The exit event does NOT mean that all stdout and stderr events have been received. + */function createProcessStream(type = 'spawn', commandOrModulePath, args = [], options = {}) {const inputOption = options.input;let input;if (inputOption != null) {input = typeof inputOption === 'string' ? _rxjsBundlesRxMinJs.Observable.of(inputOption) : inputOption;}return (0, (_event || _load_event()).observableFromSubscribeFunction)(whenShellEnvironmentLoaded).take(1).switchMap(() => {const { dontLogInNuclide, killTreeWhenDone, timeout } = options; // flowlint-next-line sketchy-null-number:off + const enforceTimeout = timeout ? x => x.timeoutWith(timeout, _rxjsBundlesRxMinJs.Observable.throw(new ProcessTimeoutError(timeout, proc))) : x => x;const proc = _child_process.default[type]((_nuclideUri || _load_nuclideUri()).default.expandHomeDir(commandOrModulePath), args, // $FlowFixMe: child_process$spawnOpts and child_process$forkOpts have incompatible stdio types. + Object.assign({}, options)); // Don't let Node throw stream errors and crash the process. Note that we never dispose of + // this because stream errors can still occur after the user unsubscribes from our process + // observable. That's okay; when the streams close, the listeners will be removed. + preventStreamsFromThrowing(proc); // If we were to connect the error handler as part of the returned observable, unsubscribing + // would cause it to be removed. That would leave no attached error handler, so node would + // throw, triggering Atom's uncaught exception handler. + const errors = _rxjsBundlesRxMinJs.Observable.fromEvent(proc, 'error').flatMap(_rxjsBundlesRxMinJs.Observable.throw).publish();errors.connect();const exitEvents = _rxjsBundlesRxMinJs.Observable.fromEvent(proc, 'exit', (exitCode, signal) => ({ kind: 'exit', exitCode, signal })).filter(isRealExit).take(1);if (dontLogInNuclide !== true) {// Log the completion of the process. Note that we intentionally don't merge this with the + // returned observable because we don't want to cancel the side-effect when the user + // unsubscribes or when the process exits ("close" events come after "exit" events). + const now = (0, (_performanceNow || _load_performanceNow()).default)();_rxjsBundlesRxMinJs.Observable.fromEvent(proc, 'close').do(() => {logCall(Math.round((0, (_performanceNow || _load_performanceNow()).default)() - now), commandOrModulePath, args);}).subscribe();}let finished = false;return enforceTimeout(_rxjsBundlesRxMinJs.Observable.using( // Log stream errors, but only for as long as you're subscribed to the process observable. + () => logStreamErrors(proc, commandOrModulePath, args, options), () => _rxjsBundlesRxMinJs.Observable.merge( // Node [delays the emission of process errors][1] by a tick in order to give + // consumers a chance to subscribe to the error event. This means that our observable + // would normally emit the process and then, a tick later, error. However, it's more + // convenient to never emit the process if there was an error. Although observables + // don't require the error to be delayed at all, the underlying event emitter + // abstraction does, so we'll just roll with that and use `pid == null` as a signal + // that an error is forthcoming. + // + // [1]: https://github.com/nodejs/node/blob/v7.10.0/lib/internal/child_process.js#L301 + proc.pid == null ? _rxjsBundlesRxMinJs.Observable.empty() : _rxjsBundlesRxMinJs.Observable.of(proc), _rxjsBundlesRxMinJs.Observable.never() // Don't complete until we say so! + )).merge( // Write any input to stdin. This is just for the side-effect. We merge it here to + // ensure that writing to the stdin stream happens after our event listeners are added. + input == null ? _rxjsBundlesRxMinJs.Observable.empty() : input.do({ next: str => {proc.stdin.write(str);}, complete: () => {proc.stdin.end();} }).ignoreElements()).takeUntil(errors).takeUntil(exitEvents).do({ error: () => {finished = true;}, complete: () => {finished = true;} })).catch(err => {// Since this utility errors *before* emitting the process, add the process to the error + // so that users can get whatever info they need off of it. + if (err instanceof Error && err.name === 'Error' && 'errno' in err) {throw new ProcessSystemError(err, proc);}throw err;}).finally(() => {// flowlint-next-line sketchy-null-mixed:off + if (!proc.wasKilled && !finished) {killProcess(proc, Boolean(killTreeWhenDone));}});});}function isRealExit(event) {// An exit signal from SIGUSR1 doesn't actually exit the process, so skip that. + return event.signal !== 'SIGUSR1';}function killWindowsProcessTree(pid) {return new Promise((resolve, reject) => {_child_process.default.exec(`taskkill /pid ${pid} /T /F`, error => {if (error == null) {reject(error);} else {resolve();}});});}function isExitErrorDefault(exit) {return exit.exitCode !== 0;}function isWindowsPlatform() {return (/^win/.test(process.platform));}function limitBufferSize(stream, maxBuffer, streamName) {if (maxBuffer == null) {return stream;}return _rxjsBundlesRxMinJs.Observable.defer(() => {let totalSize = 0;return stream.do(data => {totalSize += data.length;if (totalSize > maxBuffer) {throw new MaxBufferExceededError(streamName);}});});} /** + * Get an observable of error events for a process's streams. Note that these are represented as + * normal elements, not observable errors. + */function getStreamErrorEvents(proc) {const streams = [['stdin', proc.stdin], ['stdout', proc.stdout], ['stderr', proc.stderr]];return _rxjsBundlesRxMinJs.Observable.merge(...streams.map(([name, stream]) => stream == null ? _rxjsBundlesRxMinJs.Observable.empty() : _rxjsBundlesRxMinJs.Observable.fromEvent(stream, 'error').map(err => [err, name])));} \ No newline at end of file diff --git a/modules/nuclide-commons/promise.js b/modules/nuclide-commons/promise.js index 264e63ce..ad07f97b 100644 --- a/modules/nuclide-commons/promise.js +++ b/modules/nuclide-commons/promise.js @@ -1,628 +1,736 @@ -/** - * 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 - * @format - */ - -import invariant from 'assert'; - -type RunReturn = - | { - status: 'success', - result: T, - } - | { - status: 'outdated', - }; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.PromiseWithState = exports.asyncSome = exports.asyncObjFilter = exports.asyncFilter = exports.Deferred = exports.retryLimit = exports.TimedOutError = exports.triggerAfterWait = exports.RequestSerializer = undefined;var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -/** - * Allows a caller to ensure that the results it receives from consecutive - * promise resolutions are never outdated. Usage: - * - * var requestSerializer = new RequestSerializer(); - * - * // in some later loop: - * - * // note that you do not await the async function here -- you must pass the - * // promise it returns to `run` - * var result = await requestSerializer.run(someAsyncFunction()) - * - * if (result.status === 'success') { - * .... - * result.result - * } else if (result.status === 'outdated') { - * .... - * } - * - * The contract is that the status is 'success' if and only if this was the most - * recently dispatched call of 'run'. For example, if you call run(promise1) and - * then run(promise2), and promise2 resolves first, the second callsite would - * receive a 'success' status. If promise1 later resolved, the first callsite - * would receive an 'outdated' status. - */ -export class RequestSerializer { - _lastDispatchedOp: number; - _lastFinishedOp: number; - _latestPromise: Promise; - _waitResolve: Function; - - constructor() { - this._lastDispatchedOp = 0; - this._lastFinishedOp = 0; - this._latestPromise = new Promise((resolve, reject) => { - this._waitResolve = resolve; - }); - } - - async run(promise: Promise): Promise> { - const thisOp = this._lastDispatchedOp + 1; - this._lastDispatchedOp = thisOp; - this._latestPromise = promise; - this._waitResolve(); - const result = await promise; - if (this._lastFinishedOp < thisOp) { - this._lastFinishedOp = thisOp; - return { - status: 'success', - result, - }; - } else { - return { - status: 'outdated', - }; - } - } - - /** - * Returns a Promise that resolves to the last result of `run`, - * as soon as there are no more outstanding `run` calls. - */ - async waitForLatestResult(): Promise { - let lastPromise = null; - let result: any = null; - while (lastPromise !== this._latestPromise) { - lastPromise = this._latestPromise; - // Wait for the current last know promise to resolve, or a next run have started. - // eslint-disable-next-line no-await-in-loop - result = await new Promise((resolve, reject) => { - this._waitResolve = resolve; - this._latestPromise.then(resolve); - }); - } - return (result: T); - } - - isRunInProgress(): boolean { - return this._lastDispatchedOp > this._lastFinishedOp; - } -} - -/* - * Returns a promise that will resolve after `milliSeconds` milli seconds. - * this can be used to pause execution asynchronously. - * e.g. await sleep(1000), pauses the async flow execution for 1 second. - */ -export function sleep(milliSeconds: number): Promise { - return new Promise(resolve => { - setTimeout(resolve, milliSeconds); - }); -} - -export function nextTick(): Promise { - return new Promise(resolve => { - process.nextTick(resolve); - }); -} -/** - * Executes a provided callback only if a promise takes longer than - * `milliSeconds` milliseconds to resolve. - * - * @param `promise` the promise to wait on. - * @param `milliSeconds` max amount of time that `promise` can take to resolve - * before timeoutFn is fired. - * @param `timeoutFn` the function to execute when a promise takes longer than - * `milliSeconds` ms to resolve. - * @param `cleanupFn` the cleanup function to execute after the promise resolves. - */ -export async function triggerAfterWait( - promise: Promise, - milliSeconds: number, - timeoutFn: () => void, - cleanupFn?: () => void, -): Promise { - const timeout = setTimeout(timeoutFn, milliSeconds); - try { - return await promise; - } finally { - clearTimeout(timeout); - if (cleanupFn) { - cleanupFn(); - } - } -} -/** - * Thrown by `timeoutPromise` if the timer fires before the promise resolves/rejects. - */ -export class TimedOutError extends Error { - timeout: number; - constructor(milliseconds: number) { - super(`Timed out after ${String(milliseconds)} ms`); - this.timeout = milliseconds; - } -} -/** - * Returns a Promise that resolves to the same value as the given promise, or rejects with - * `TimedOutError` if it takes longer than `milliseconds` milliseconds. - */ -export function timeoutPromise( - promise: Promise, - milliseconds: number, -): Promise { - return new Promise((resolve, reject) => { - let timeout = setTimeout(() => { - timeout = null; - reject(new TimedOutError(milliseconds)); - // This gives useless error.stack results. - // We could capture the stack pre-emptively at the start - // of this method if we wanted useful ones. - }, milliseconds); - promise - .then(value => { - if (timeout != null) { - clearTimeout(timeout); - } - resolve(value); - }) - .catch(value => { - if (timeout != null) { - clearTimeout(timeout); - } - reject(value); - }); - }); -} -// An DeadlineRequest parameter to an async method is a way of *requesting* that -// method to throw a TimedOutError if it doesn't complete in a certain time. -// It's just a request -- the async method will typically honor the request -// by passing the parameter on to ALL subsidiary async methods that it awaits, -// or by calling expirePromise to enforce a timeout, or similar. -// -// In cases where a method supports DeadlineRequest but you don't trust it, do -// `await timeoutAfterDeadline(deadline, untrusted.foo(deadline-1000))` so you -// ask it nicely but if it doesn't give its own more-specific deadline message -// within a 1000ms grace period then you force matters. -// -// Under the hood an DeadlineRequest is just a timestamp of the time by which -// the operation should complete. This makes it compositional (better than -// "delay" parameters) and safely remotable (better than "CancellationToken" -// parameters) so long as clocks are in sync. In all other respects it's less -// versatile than CancellationTokens. -export type DeadlineRequest = number; -export function createDeadline(delay: number): DeadlineRequest { - return Date.now() + delay; -} -export function timeoutAfterDeadline( - deadline: DeadlineRequest, - promise: Promise, -): Promise { - const delay = deadline - Date.now(); - return timeoutPromise(promise, delay < 0 ? 0 : delay); -} /** - * Call an async function repeatedly with a maximum number of trials limit, - * until a valid result that's defined by a validation function. - * A failed call can result from an async thrown exception, or invalid result. - * - * @param `retryFunction` the async logic that's wanted to be retried. - * @param `validationFunction` the validation function that decides whether a response is valid. - * @param `maximumTries` the number of times the `retryFunction` can fail to get a valid - * response before the `retryLimit` is terminated reporting an error. - * @param `retryIntervalMs` optional, the number of milliseconds to wait between trials, if wanted. - * - * If an exception is encountered on the last trial, the exception is thrown. - * If no valid response is found, an exception is thrown. - */ -export async function retryLimit( - retryFunction: () => Promise, - validationFunction: (result: T) => boolean, - maximumTries: number, - retryIntervalMs?: number = 0, -): Promise { - let result = null; - let tries = 0; - let lastError = null; - while (tries === 0 || tries < maximumTries) { + * Executes a provided callback only if a promise takes longer than + * `milliSeconds` milliseconds to resolve. + * + * @param `promise` the promise to wait on. + * @param `milliSeconds` max amount of time that `promise` can take to resolve + * before timeoutFn is fired. + * @param `timeoutFn` the function to execute when a promise takes longer than + * `milliSeconds` ms to resolve. + * @param `cleanupFn` the cleanup function to execute after the promise resolves. + */let triggerAfterWait = exports.triggerAfterWait = (() => {var _ref = (0, _asyncToGenerator.default)( + function* ( + promise, + milliSeconds, + timeoutFn, + cleanupFn) + { + const timeout = setTimeout(timeoutFn, milliSeconds); try { - // eslint-disable-next-line no-await-in-loop - result = await retryFunction(); - lastError = null; - if (validationFunction(result)) { - return result; + return yield promise; + } finally { + clearTimeout(timeout); + if (cleanupFn) { + cleanupFn(); } - } catch (error) { - lastError = error; - result = null; - } - - if (++tries < maximumTries && retryIntervalMs !== 0) { - // eslint-disable-next-line no-await-in-loop - await sleep(retryIntervalMs); } - } - if (lastError != null) { - throw lastError; - } else if (tries === maximumTries) { - throw new Error('No valid response found!'); - } else { - return ((result: any): T); - } -} + });return function triggerAfterWait(_x, _x2, _x3, _x4) {return _ref.apply(this, arguments);};})(); /** - * Limits async function execution parallelism to only one at a time. - * Hence, if a call is already running, it will wait for it to finish, - * then start the next async execution, but if called again while not finished, - * it will return the scheduled execution promise. - * - * Sample Usage: - * ``` - * let i = 1; - * const oneExecAtATime = oneParallelAsyncCall(() => { - * return next Promise((resolve, reject) => { - * setTimeout(200, () => resolve(i++)); - * }); - * }); - * - * const result1Promise = oneExecAtATime(); // Start an async, and resolve to 1 in 200 ms. - * const result2Promise = oneExecAtATime(); // Schedule the next async, and resolve to 2 in 400 ms. - * const result3Promise = oneExecAtATime(); // Reuse scheduled promise and resolve to 2 in 400 ms. - * ``` - */ -export function serializeAsyncCall( - asyncFun: () => Promise, -): () => Promise { - let scheduledCall = null; - let pendingCall = null; - const startAsyncCall = () => { - const resultPromise = asyncFun(); - pendingCall = resultPromise.then( - () => (pendingCall = null), - () => (pendingCall = null), - ); - return resultPromise; - }; - const callNext = () => { - scheduledCall = null; - return startAsyncCall(); - }; - const scheduleNextCall = () => { - if (scheduledCall == null) { - invariant(pendingCall, 'pendingCall must not be null!'); - scheduledCall = pendingCall.then(callNext, callNext); - } - return scheduledCall; - }; - return () => { - if (pendingCall == null) { - return startAsyncCall(); - } else { - return scheduleNextCall(); - } - }; -} + * Thrown by `timeoutPromise` if the timer fires before the promise resolves/rejects. + */ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -/** - * Provides a promise along with methods to change its state. Our version of the non-standard - * `Promise.defer()`. - * - * IMPORTANT: This should almost never be used!! Instead, use the Promise constructor. See - * - */ -export class Deferred { - promise: Promise; - resolve: (value: T) => void; - reject: (error: Error) => void; - - constructor() { - this.promise = new Promise((resolve, reject) => { - this.resolve = resolve; - this.reject = reject; - }); - } -} -/** - * Returns a value derived asynchronously from an element in the items array. - * The test function is applied sequentially to each element in items until - * one returns a Promise that resolves to a non-null value. When this happens, - * the Promise returned by this method will resolve to that non-null value. If - * no such Promise is produced, then the Promise returned by this function - * will resolve to null. - * - * @param items Array of elements that will be passed to test, one at a time. - * @param test Will be called with each item and must return either: - * (1) A "thenable" (i.e, a Promise or promise-like object) that resolves - * to a derived value (that will be returned) or null. - * (2) null. - * In both cases where null is returned, test will be applied to the next - * item in the array. - * @param thisArg Receiver that will be used when test is called. - * @return Promise that resolves to an asynchronously derived value or null. - */ -export function asyncFind( - items_: Array, - test: (t: T) => ?Promise, - thisArg?: mixed, -): Promise { - let items = items_; - return new Promise((resolve, reject) => { - // Create a local copy of items to defend against the caller modifying the - // array before this Promise is resolved. - items = items.slice(); - const numItems = items.length; - const next = async function(index) { - if (index === numItems) { - resolve(null); - return; - } - const item = items[index]; - const result = await test.call(thisArg, item); - if (result != null) { - resolve(result); - } else { - next(index + 1); - } - }; - - next(0); - }); -} - -export function denodeify( - f: (...args: Array) => any, -): (...args: Array) => Promise { - return function(...args: Array) { - return new Promise((resolve, reject) => { - function callback(error, result) { - if (error) { - reject(error); - } else { - resolve(result); - } - } - f.apply(this, args.concat([callback])); - }); - }; -} /** - * A Promise utility that runs a maximum of limit async operations at a time - * iterating over an array and returning the result of executions. - * e.g. to limit the number of file reads to 5, - * replace the code: - * var fileContents = await Promise.all(filePaths.map(fsPromise.readFile)) - * with: - * var fileContents = await asyncLimit(filePaths, 5, fsPromise.readFile) - * - * This is particulrily useful to limit IO operations to a configurable maximum (to avoid - * blocking), while enjoying the configured level of parallelism. - * - * @param array the array of items for iteration. - * @param limit the configurable number of parallel async operations. - * @param mappingFunction the async Promise function that could return a useful result. - */ -export function asyncLimit( - array: Array, - limit: number, - mappingFunction: (item: T) => Promise, -): Promise> { - const result: Array = new Array(array.length); - let parallelPromises = 0; - let index = 0; - - let parallelLimit = Math.min(limit, array.length) || 1; - - return new Promise((resolve, reject) => { - const runPromise = async () => { - if (index === array.length) { - if (parallelPromises === 0) { - resolve(result); - } - return; - } - ++parallelPromises; - const i = index++; + * Call an async function repeatedly with a maximum number of trials limit, + * until a valid result that's defined by a validation function. + * A failed call can result from an async thrown exception, or invalid result. + * + * @param `retryFunction` the async logic that's wanted to be retried. + * @param `validationFunction` the validation function that decides whether a response is valid. + * @param `maximumTries` the number of times the `retryFunction` can fail to get a valid + * response before the `retryLimit` is terminated reporting an error. + * @param `retryIntervalMs` optional, the number of milliseconds to wait between trials, if wanted. + * + * If an exception is encountered on the last trial, the exception is thrown. + * If no valid response is found, an exception is thrown. + */let retryLimit = exports.retryLimit = (() => {var _ref2 = (0, _asyncToGenerator.default)( + function* ( + retryFunction, + validationFunction, + maximumTries, + retryIntervalMs = 0) + { + let result = null; + let tries = 0; + let lastError = null; + while (tries === 0 || tries < maximumTries) { try { - result[i] = await mappingFunction(array[i]); - } catch (e) { - reject(e); + // eslint-disable-next-line no-await-in-loop + result = yield retryFunction(); + lastError = null; + if (validationFunction(result)) { + return result; + } + } catch (error) { + lastError = error; + result = null; } - --parallelPromises; - runPromise(); - }; - while (parallelLimit--) { - runPromise(); - } - }); -} - -/** - * `filter` Promise utility that allows filtering an array with an async Promise function. - * It's an alternative to `Array.prototype.filter` that accepts an async function. - * You can optionally configure a limit to set the maximum number of async operations at a time. - * - * Previously, with the `Promise.all` primitive, we can't set the parallelism limit and we have to - * `filter`, so, we replace the old `filter` code: - * var existingFilePaths = []; - * await Promise.all(filePaths.map(async (filePath) => { - * if (await fsPromise.exists(filePath)) { - * existingFilePaths.push(filePath); - * } - * })); - * with limit 5 parallel filesystem operations at a time: - * var existingFilePaths = await asyncFilter(filePaths, fsPromise.exists, 5); - * - * @param array the array of items for `filter`ing. - * @param filterFunction the async `filter` function that returns a Promise that resolves to a - * boolean. - * @param limit the configurable number of parallel async operations. - */ -export async function asyncFilter( - array: Array, - filterFunction: (item: T) => Promise, - limit?: number, -): Promise> { - const filteredList = []; - // flowlint-next-line sketchy-null-number:off - await asyncLimit(array, limit || array.length, async (item: T) => { - if (await filterFunction(item)) { - filteredList.push(item); + if (++tries < maximumTries && retryIntervalMs !== 0) { + // eslint-disable-next-line no-await-in-loop + yield sleep(retryIntervalMs); + } } - }); - return filteredList; -} - -export async function asyncObjFilter( - obj: {[key: string]: T}, - filterFunction: (item: T, key: string) => Promise, - limit?: number, -): Promise<{[key: string]: T}> { - const keys = Object.keys(obj); - const filteredObj = {}; - // flowlint-next-line sketchy-null-number:off - await asyncLimit(keys, limit || keys.length, async (key: string) => { - const item = obj[key]; - if (await filterFunction(item, key)) { - filteredObj[key] = item; + if (lastError != null) { + throw lastError; + } else if (tries === maximumTries) { + throw new Error('No valid response found!'); + } else { + return result; } - }); - return filteredObj; -} + });return function retryLimit(_x5, _x6, _x7) {return _ref2.apply(this, arguments);};})(); /** - * `some` Promise utility that allows `some` an array with an async Promise some function. - * It's an alternative to `Array.prototype.some` that accepts an async some function. - * You can optionally configure a limit to set the maximum number of async operations at a time. - * - * Previously, with the Promise.all primitive, we can't set the parallelism limit and we have to - * `some`, so, we replace the old `some` code: - * var someFileExist = false; - * await Promise.all(filePaths.map(async (filePath) => { - * if (await fsPromise.exists(filePath)) { - * someFileExist = true; - * } - * })); - * with limit 5 parallel filesystem operations at a time: - * var someFileExist = await asyncSome(filePaths, fsPromise.exists, 5); - * - * @param array the array of items for `some`ing. - * @param someFunction the async `some` function that returns a Promise that resolves to a - * boolean. - * @param limit the configurable number of parallel async operations. - */ -export async function asyncSome( - array: Array, - someFunction: (item: T) => Promise, - limit?: number, -): Promise { - let resolved = false; - // flowlint-next-line sketchy-null-number:off - await asyncLimit(array, limit || array.length, async (item: T) => { - if (resolved) { - // We don't need to call the someFunction anymore or wait any longer. - return; - } - if (await someFunction(item)) { - resolved = true; - } - }); - return resolved; -} + * Limits async function execution parallelism to only one at a time. + * Hence, if a call is already running, it will wait for it to finish, + * then start the next async execution, but if called again while not finished, + * it will return the scheduled execution promise. + * + * Sample Usage: + * ``` + * let i = 1; + * const oneExecAtATime = oneParallelAsyncCall(() => { + * return next Promise((resolve, reject) => { + * setTimeout(200, () => resolve(i++)); + * }); + * }); + * + * const result1Promise = oneExecAtATime(); // Start an async, and resolve to 1 in 200 ms. + * const result2Promise = oneExecAtATime(); // Schedule the next async, and resolve to 2 in 400 ms. + * const result3Promise = oneExecAtATime(); // Reuse scheduled promise and resolve to 2 in 400 ms. + * ``` + */ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /** - * Check if an object is Promise by testing if it has a `then` function property. - */ -export function isPromise(object: any): boolean { - return ( - Boolean(object) && - typeof object === 'object' && - typeof object.then === 'function' - ); -} + * `filter` Promise utility that allows filtering an array with an async Promise function. + * It's an alternative to `Array.prototype.filter` that accepts an async function. + * You can optionally configure a limit to set the maximum number of async operations at a time. + * + * Previously, with the `Promise.all` primitive, we can't set the parallelism limit and we have to + * `filter`, so, we replace the old `filter` code: + * var existingFilePaths = []; + * await Promise.all(filePaths.map(async (filePath) => { + * if (await fsPromise.exists(filePath)) { + * existingFilePaths.push(filePath); + * } + * })); + * with limit 5 parallel filesystem operations at a time: + * var existingFilePaths = await asyncFilter(filePaths, fsPromise.exists, 5); + * + * @param array the array of items for `filter`ing. + * @param filterFunction the async `filter` function that returns a Promise that resolves to a + * boolean. + * @param limit the configurable number of parallel async operations. + */let asyncFilter = exports.asyncFilter = (() => {var _ref5 = (0, _asyncToGenerator.default)( + function* ( + array, + filterFunction, + limit) + { + const filteredList = []; + // flowlint-next-line sketchy-null-number:off + yield asyncLimit(array, limit || array.length, (() => {var _ref6 = (0, _asyncToGenerator.default)(function* (item) { + if (yield filterFunction(item)) { + filteredList.push(item); + } + });return function (_x12) {return _ref6.apply(this, arguments);};})()); + return filteredList; + });return function asyncFilter(_x9, _x10, _x11) {return _ref5.apply(this, arguments);};})();let asyncObjFilter = exports.asyncObjFilter = (() => {var _ref7 = (0, _asyncToGenerator.default)( + + function* ( + obj, + filterFunction, + limit) + { + const keys = Object.keys(obj); + const filteredObj = {}; + // flowlint-next-line sketchy-null-number:off + yield asyncLimit(keys, limit || keys.length, (() => {var _ref8 = (0, _asyncToGenerator.default)(function* (key) { + const item = obj[key]; + if (yield filterFunction(item, key)) { + filteredObj[key] = item; + } + });return function (_x16) {return _ref8.apply(this, arguments);};})()); + return filteredObj; + });return function asyncObjFilter(_x13, _x14, _x15) {return _ref7.apply(this, arguments);};})(); /** - * We can't name a function 'finally', so use lastly instead. - * fn() will be executed (and completed) after the provided promise resolves/rejects. - */ -export function lastly( - promise: Promise, - fn: () => Promise | mixed, -): Promise { - return promise.then( - ret => { - return Promise.resolve(fn()).then(() => ret); - }, - err => { - return Promise.resolve(fn()).then(() => Promise.reject(err)); - }, - ); -} + * `some` Promise utility that allows `some` an array with an async Promise some function. + * It's an alternative to `Array.prototype.some` that accepts an async some function. + * You can optionally configure a limit to set the maximum number of async operations at a time. + * + * Previously, with the Promise.all primitive, we can't set the parallelism limit and we have to + * `some`, so, we replace the old `some` code: + * var someFileExist = false; + * await Promise.all(filePaths.map(async (filePath) => { + * if (await fsPromise.exists(filePath)) { + * someFileExist = true; + * } + * })); + * with limit 5 parallel filesystem operations at a time: + * var someFileExist = await asyncSome(filePaths, fsPromise.exists, 5); + * + * @param array the array of items for `some`ing. + * @param someFunction the async `some` function that returns a Promise that resolves to a + * boolean. + * @param limit the configurable number of parallel async operations. + */let asyncSome = exports.asyncSome = (() => {var _ref9 = (0, _asyncToGenerator.default)( + function* ( + array, + someFunction, + limit) + { + let resolved = false; + // flowlint-next-line sketchy-null-number:off + yield asyncLimit(array, limit || array.length, (() => {var _ref10 = (0, _asyncToGenerator.default)(function* (item) { + if (resolved) { + // We don't need to call the someFunction anymore or wait any longer. + return; + } + if (yield someFunction(item)) { + resolved = true; + } + });return function (_x20) {return _ref10.apply(this, arguments);};})()); + return resolved; + });return function asyncSome(_x17, _x18, _x19) {return _ref9.apply(this, arguments);};})(); /** - * With a pure promise object, there's no way to tell synchronously - * whether or not it has 'settled' (i.e. been fulfilled or rejected). - * Here we provide a wrapper that provides that information. - */ -export type PromiseState = - | {kind: 'pending'} - | {kind: 'fulfilled', value: T} - | {kind: 'rejected', error: any}; - -export class PromiseWithState { - _promise: Promise; - _state: PromiseState; - - constructor(promise: Promise) { - this._state = {kind: 'pending'}; - this._promise = promise.then( - value => { - this._state = {kind: 'fulfilled', value}; - return value; - }, - error => { - this._state = {kind: 'rejected', error}; - throw error; - }, - ); - } - - getPromise(): Promise { - return this._promise; - } - - getState(): PromiseState { - return this._state; - } -} - -export function delayTime(ms: number): Promise { - return new Promise((resolve, reject) => { - setTimeout(resolve, ms); - }); -} + * Check if an object is Promise by testing if it has a `then` function property. + */exports.sleep = sleep;exports.nextTick = nextTick;exports.timeoutPromise = timeoutPromise;exports.createDeadline = createDeadline;exports.timeoutAfterDeadline = timeoutAfterDeadline;exports.serializeAsyncCall = serializeAsyncCall;exports.asyncFind = asyncFind;exports.denodeify = denodeify;exports.asyncLimit = asyncLimit;exports. +isPromise = isPromise;exports. + + + + + + + + + + + +lastly = lastly;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +delayTime = delayTime;function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * Allows a caller to ensure that the results it receives from consecutive + * promise resolutions are never outdated. Usage: + * + * var requestSerializer = new RequestSerializer(); + * + * // in some later loop: + * + * // note that you do not await the async function here -- you must pass the + * // promise it returns to `run` + * var result = await requestSerializer.run(someAsyncFunction()) + * + * if (result.status === 'success') { + * .... + * result.result + * } else if (result.status === 'outdated') { + * .... + * } + * + * The contract is that the status is 'success' if and only if this was the most + * recently dispatched call of 'run'. For example, if you call run(promise1) and + * then run(promise2), and promise2 resolves first, the second callsite would + * receive a 'success' status. If promise1 later resolved, the first callsite + * would receive an 'outdated' status. + */ /** + * 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. + * + * + * @format + */class RequestSerializer {constructor() {this._lastDispatchedOp = 0;this._lastFinishedOp = 0;this._latestPromise = new Promise((resolve, reject) => {this._waitResolve = resolve;});}run(promise) {var _this = this;return (0, _asyncToGenerator.default)(function* () {const thisOp = _this._lastDispatchedOp + 1;_this._lastDispatchedOp = thisOp;_this._latestPromise = promise;_this._waitResolve();const result = yield promise;if (_this._lastFinishedOp < thisOp) {_this._lastFinishedOp = thisOp;return { status: 'success', result };} else {return { status: 'outdated' };}})();} /** + * Returns a Promise that resolves to the last result of `run`, + * as soon as there are no more outstanding `run` calls. + */waitForLatestResult() {var _this2 = this;return (0, _asyncToGenerator.default)(function* () {let lastPromise = null;let result = null;while (lastPromise !== _this2._latestPromise) {lastPromise = _this2._latestPromise; // Wait for the current last know promise to resolve, or a next run have started. + // eslint-disable-next-line no-await-in-loop + result = yield new Promise(function (resolve, reject) {_this2._waitResolve = resolve;_this2._latestPromise.then(resolve);});}return result;})();}isRunInProgress() {return this._lastDispatchedOp > this._lastFinishedOp;}}exports.RequestSerializer = RequestSerializer; /* + * Returns a promise that will resolve after `milliSeconds` milli seconds. + * this can be used to pause execution asynchronously. + * e.g. await sleep(1000), pauses the async flow execution for 1 second. + */function sleep(milliSeconds) {return new Promise(resolve => {setTimeout(resolve, milliSeconds);});}function nextTick() {return new Promise(resolve => {process.nextTick(resolve);});}class TimedOutError extends Error {constructor(milliseconds) {super(`Timed out after ${String(milliseconds)} ms`);this.timeout = milliseconds;}}exports.TimedOutError = TimedOutError; /** + * Returns a Promise that resolves to the same value as the given promise, or rejects with + * `TimedOutError` if it takes longer than `milliseconds` milliseconds. + */function timeoutPromise(promise, milliseconds) {return new Promise((resolve, reject) => {let timeout = setTimeout(() => {timeout = null;reject(new TimedOutError(milliseconds)); // This gives useless error.stack results. + // We could capture the stack pre-emptively at the start + // of this method if we wanted useful ones. + }, milliseconds);promise.then(value => {if (timeout != null) {clearTimeout(timeout);}resolve(value);}).catch(value => {if (timeout != null) {clearTimeout(timeout);}reject(value);});});} // An DeadlineRequest parameter to an async method is a way of *requesting* that +// method to throw a TimedOutError if it doesn't complete in a certain time. +// It's just a request -- the async method will typically honor the request +// by passing the parameter on to ALL subsidiary async methods that it awaits, +// or by calling expirePromise to enforce a timeout, or similar. +// +// In cases where a method supports DeadlineRequest but you don't trust it, do +// `await timeoutAfterDeadline(deadline, untrusted.foo(deadline-1000))` so you +// ask it nicely but if it doesn't give its own more-specific deadline message +// within a 1000ms grace period then you force matters. +// +// Under the hood an DeadlineRequest is just a timestamp of the time by which +// the operation should complete. This makes it compositional (better than +// "delay" parameters) and safely remotable (better than "CancellationToken" +// parameters) so long as clocks are in sync. In all other respects it's less +// versatile than CancellationTokens. +function createDeadline(delay) {return Date.now() + delay;}function timeoutAfterDeadline(deadline, promise) {const delay = deadline - Date.now();return timeoutPromise(promise, delay < 0 ? 0 : delay);}function serializeAsyncCall(asyncFun) {let scheduledCall = null;let pendingCall = null;const startAsyncCall = () => {const resultPromise = asyncFun();pendingCall = resultPromise.then(() => pendingCall = null, () => pendingCall = null);return resultPromise;};const callNext = () => {scheduledCall = null;return startAsyncCall();};const scheduleNextCall = () => {if (scheduledCall == null) {if (!pendingCall) {throw new Error('pendingCall must not be null!');}scheduledCall = pendingCall.then(callNext, callNext);}return scheduledCall;};return () => {if (pendingCall == null) {return startAsyncCall();} else {return scheduleNextCall();}};} /** + * Provides a promise along with methods to change its state. Our version of the non-standard + * `Promise.defer()`. + * + * IMPORTANT: This should almost never be used!! Instead, use the Promise constructor. See + * + */class Deferred {constructor() {this.promise = new Promise((resolve, reject) => {this.resolve = resolve;this.reject = reject;});}}exports.Deferred = Deferred; /** + * Returns a value derived asynchronously from an element in the items array. + * The test function is applied sequentially to each element in items until + * one returns a Promise that resolves to a non-null value. When this happens, + * the Promise returned by this method will resolve to that non-null value. If + * no such Promise is produced, then the Promise returned by this function + * will resolve to null. + * + * @param items Array of elements that will be passed to test, one at a time. + * @param test Will be called with each item and must return either: + * (1) A "thenable" (i.e, a Promise or promise-like object) that resolves + * to a derived value (that will be returned) or null. + * (2) null. + * In both cases where null is returned, test will be applied to the next + * item in the array. + * @param thisArg Receiver that will be used when test is called. + * @return Promise that resolves to an asynchronously derived value or null. + */function asyncFind(items_, test, thisArg) {let items = items_;return new Promise((resolve, reject) => {// Create a local copy of items to defend against the caller modifying the + // array before this Promise is resolved. + items = items.slice();const numItems = items.length;const next = (() => {var _ref3 = (0, _asyncToGenerator.default)(function* (index) {if (index === numItems) {resolve(null);return;}const item = items[index];const result = yield test.call(thisArg, item);if (result != null) {resolve(result);} else {next(index + 1);}});return function next(_x8) {return _ref3.apply(this, arguments);};})();next(0);});}function denodeify(f) {return function (...args) {return new Promise((resolve, reject) => {function callback(error, result) {if (error) {reject(error);} else {resolve(result);}}f.apply(this, args.concat([callback]));});};} /** + * A Promise utility that runs a maximum of limit async operations at a time + * iterating over an array and returning the result of executions. + * e.g. to limit the number of file reads to 5, + * replace the code: + * var fileContents = await Promise.all(filePaths.map(fsPromise.readFile)) + * with: + * var fileContents = await asyncLimit(filePaths, 5, fsPromise.readFile) + * + * This is particulrily useful to limit IO operations to a configurable maximum (to avoid + * blocking), while enjoying the configured level of parallelism. + * + * @param array the array of items for iteration. + * @param limit the configurable number of parallel async operations. + * @param mappingFunction the async Promise function that could return a useful result. + */function asyncLimit(array, limit, mappingFunction) {const result = new Array(array.length);let parallelPromises = 0;let index = 0;let parallelLimit = Math.min(limit, array.length) || 1;return new Promise((resolve, reject) => {const runPromise = (() => {var _ref4 = (0, _asyncToGenerator.default)(function* () {if (index === array.length) {if (parallelPromises === 0) {resolve(result);}return;}++parallelPromises;const i = index++;try {result[i] = yield mappingFunction(array[i]);} catch (e) {reject(e);}--parallelPromises;runPromise();});return function runPromise() {return _ref4.apply(this, arguments);};})();while (parallelLimit--) {runPromise();}});}function isPromise(object) {return Boolean(object) && typeof object === 'object' && typeof object.then === 'function';} /** + * We can't name a function 'finally', so use lastly instead. + * fn() will be executed (and completed) after the provided promise resolves/rejects. + */function lastly(promise, fn) {return promise.then(ret => {return Promise.resolve(fn()).then(() => ret);}, err => {return Promise.resolve(fn()).then(() => Promise.reject(err));});} /** + * With a pure promise object, there's no way to tell synchronously + * whether or not it has 'settled' (i.e. been fulfilled or rejected). + * Here we provide a wrapper that provides that information. + */class PromiseWithState {constructor(promise) {this._state = { kind: 'pending' };this._promise = promise.then(value => {this._state = { kind: 'fulfilled', value };return value;}, error => {this._state = { kind: 'rejected', error };throw error;});}getPromise() {return this._promise;}getState() {return this._state;}}exports.PromiseWithState = PromiseWithState;function delayTime(ms) {return new Promise((resolve, reject) => {setTimeout(resolve, ms);});} \ No newline at end of file diff --git a/modules/nuclide-commons/range.js b/modules/nuclide-commons/range.js index 63dbe0eb..9af10fea 100644 --- a/modules/nuclide-commons/range.js +++ b/modules/nuclide-commons/range.js @@ -1,65 +1,73 @@ -/** - * 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 - * @format - */ - -export function wordAtPositionFromBuffer( - buffer: atom$TextBuffer | simpleTextBuffer$TextBuffer, - position: atom$PointObject, - wordRegex: RegExp, -): ?{wordMatch: Array, range: atom$Range} { - const {row, column} = position; - const rowRange = buffer.rangeForRow(row); - let matchData; - // Extract the expression from the row text. - buffer.scanInRange(wordRegex, rowRange, data => { - const {range} = data; - if ( - range.start.isLessThanOrEqual(position) && - range.end.isGreaterThan(position) - ) { - matchData = data; - } - // Stop the scan if the scanner has passed our position. - if (range.end.column > column) { - data.stop(); - } - }); - if (matchData) { - return { - wordMatch: matchData.match, - range: matchData.range, - }; - } else { - return null; - } -} - -// Matches a regex on the text of the line ending at endPosition. +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + +wordAtPositionFromBuffer = wordAtPositionFromBuffer;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +matchRegexEndingAt = matchRegexEndingAt;exports. + + + + + + + + + +isPositionInRange = isPositionInRange; /** + * 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. + * + * + * @format + */function wordAtPositionFromBuffer(buffer, position, wordRegex) {const { row, column } = position;const rowRange = buffer.rangeForRow(row);let matchData; // Extract the expression from the row text. + buffer.scanInRange(wordRegex, rowRange, data => {const { range } = data;if (range.start.isLessThanOrEqual(position) && range.end.isGreaterThan(position)) {matchData = data;} // Stop the scan if the scanner has passed our position. + if (range.end.column > column) {data.stop();}});if (matchData) {return { wordMatch: matchData.match, range: matchData.range };} else {return null;}} // Matches a regex on the text of the line ending at endPosition. // regex should end with a '$'. // Useful for autocomplete. -export function matchRegexEndingAt( - buffer: atom$TextBuffer | simpleTextBuffer$TextBuffer, - endPosition: atom$PointObject, - regex: RegExp, -): ?string { - const line = buffer.getTextInRange([[endPosition.row, 0], endPosition]); - const match = regex.exec(line); - return match == null ? null : match[0]; -} - -export function isPositionInRange( - position: atom$Point, - range: atom$Range | Array, -): boolean { - return Array.isArray(range) - ? range.some(r => r.containsPoint(position)) - : range.containsPoint(position); -} +function matchRegexEndingAt(buffer, endPosition, regex) {const line = buffer.getTextInRange([[endPosition.row, 0], endPosition]);const match = regex.exec(line);return match == null ? null : match[0];}function isPositionInRange(position, range) {return Array.isArray(range) ? range.some(r => r.containsPoint(position)) : range.containsPoint(position);} \ No newline at end of file diff --git a/modules/nuclide-commons/redux-observable.js b/modules/nuclide-commons/redux-observable.js index 0d321166..a38dd673 100644 --- a/modules/nuclide-commons/redux-observable.js +++ b/modules/nuclide-commons/redux-observable.js @@ -1,16 +1,84 @@ -/** - * 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 - * @format - */ - -// Derived from because their version +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.ActionsObservable = undefined;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +combineEpics = combineEpics;exports. + + + + + + + + + + +createEpicMiddleware = createEpicMiddleware;var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); // This should be { type: readonly string } when we get readonly props. Because this is used with +// disjoint unions we can't use `string` here due to mutation concerns. Flow doesn't know that we +// aren't going to mutate the objects with a random string value so it can't allow us to pass a +// specific action type into something of type { type: string } +function combineEpics(...epics) {return (actions, store, extra) => {const streams = epics.map(epic => epic(actions, store, extra));return _rxjsBundlesRxMinJs.Observable.merge(...streams);};} /** + * 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. + * + * + * @format + */ // Derived from because their version // imports an Rx operator module and we use a bundle. Original license follows: // // The MIT License (MIT) @@ -34,75 +102,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. - -import {Observable, Subject} from 'rxjs'; - -// This should be { type: readonly string } when we get readonly props. Because this is used with -// disjoint unions we can't use `string` here due to mutation concerns. Flow doesn't know that we -// aren't going to mutate the objects with a random string value so it can't allow us to pass a -// specific action type into something of type { type: string } -type Action = {type: any}; -type Store = { - dispatch(action: T): void, - getState(): U, -}; -type Next = (action: T) => T; -export type Epic = ( - actions: ActionsObservable, - store: Store, - extra: E, -) => Observable; - -export function combineEpics( - ...epics: Array> -): Epic { - return (actions: ActionsObservable, store: Store, extra: E) => { - const streams: Array> = epics.map(epic => - epic(actions, store, extra), - ); - return Observable.merge(...streams); - }; -} - -export function createEpicMiddleware( - rootEpic?: Epic, -) { - const actions = new Subject(); - const actionsObs = new ActionsObservable(actions); - - return (store: Store) => (next: Next) => { - if (rootEpic != null) { - rootEpic(actionsObs, store).subscribe(store.dispatch); - } - return (action: T) => { - const result = next(action); - actions.next(action); - return result; - }; - }; -} - -export class ActionsObservable extends Observable { - operator: any; - - constructor(actionsSubject: Observable) { - super(); - this.source = actionsSubject; - } - - lift(operator: any): Observable { - const observable = new ActionsObservable(this); - observable.operator = operator; - return observable; - } - - ofType(...keys: Array): ActionsObservable { - const result = this.filter(({type}) => { - const len = keys.length; - if (len === 1) { - return type === keys[0]; - } else { - for (let i = 0; i < len; i++) { +function createEpicMiddleware(rootEpic) {const actions = new _rxjsBundlesRxMinJs.Subject();const actionsObs = new ActionsObservable(actions);return store => next => {if (rootEpic != null) {rootEpic(actionsObs, store).subscribe(store.dispatch);}return action => {const result = next(action);actions.next(action);return result;};};}class ActionsObservable extends _rxjsBundlesRxMinJs.Observable {constructor(actionsSubject) {super();this.source = actionsSubject;}lift(operator) {const observable = new ActionsObservable(this);observable.operator = operator;return observable;}ofType(...keys) {const result = this.filter(({ type }) => {const len = keys.length;if (len === 1) {return type === keys[0];} else {for (let i = 0; i < len; i++) { if (keys[i] === type) { return true; } @@ -110,6 +110,5 @@ export class ActionsObservable extends Observable { } return false; }); - return ((result: any): ActionsObservable); - } -} + return result; + }}exports.ActionsObservable = ActionsObservable; \ No newline at end of file diff --git a/modules/nuclide-commons/spec/AbortController-spec.js b/modules/nuclide-commons/spec/AbortController-spec.js index 3da5a358..4d8905ae 100644 --- a/modules/nuclide-commons/spec/AbortController-spec.js +++ b/modules/nuclide-commons/spec/AbortController-spec.js @@ -1,20 +1,20 @@ -/** - * 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 - * @format - */ - -import AbortController from '../AbortController'; +'use strict';var _AbortController; + + + + + + + + + + + +function _load_AbortController() {return _AbortController = _interopRequireDefault(require('../AbortController'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} describe('AbortController', () => { it('dispatches abort() events', () => { - const controller = new AbortController(); + const controller = new (_AbortController || _load_AbortController()).default(); expect(controller.signal.aborted).toBe(false); const spy = jasmine.createSpy('onabort'); @@ -31,7 +31,7 @@ describe('AbortController', () => { }); it('dispatches abort() events via addEventListener', () => { - const controller = new AbortController(); + const controller = new (_AbortController || _load_AbortController()).default(); const spy = jasmine.createSpy('onabort'); controller.signal.addEventListener('abort', spy); @@ -40,4 +40,14 @@ describe('AbortController', () => { expect(controller.signal.aborted).toBe(true); expect(spy).toHaveBeenCalled(); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/spec/BatchProcessedQueue-spec.js b/modules/nuclide-commons/spec/BatchProcessedQueue-spec.js index df865a6f..1cdaf3ac 100644 --- a/modules/nuclide-commons/spec/BatchProcessedQueue-spec.js +++ b/modules/nuclide-commons/spec/BatchProcessedQueue-spec.js @@ -1,21 +1,21 @@ -/** - * 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 - * @format - */ - -import BatchProcessedQueue from '../BatchProcessedQueue'; +'use strict';var _BatchProcessedQueue; + + + + + + + + + + + +function _load_BatchProcessedQueue() {return _BatchProcessedQueue = _interopRequireDefault(require('../BatchProcessedQueue'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} describe('analytics - BatchProcessedQueue', () => { it('regular operation', () => { const handler = jasmine.createSpy('handler'); - const queue = new BatchProcessedQueue(5000, handler); + const queue = new (_BatchProcessedQueue || _load_BatchProcessedQueue()).default(5000, handler); queue.add(1); queue.add(2); @@ -33,4 +33,14 @@ describe('analytics - BatchProcessedQueue', () => { advanceClock(10000); expect(handler).toHaveBeenCalledWith([42]); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/spec/ConfigCache-spec.js b/modules/nuclide-commons/spec/ConfigCache-spec.js index 7de4b345..da94c06e 100644 --- a/modules/nuclide-commons/spec/ConfigCache-spec.js +++ b/modules/nuclide-commons/spec/ConfigCache-spec.js @@ -1,81 +1,81 @@ -/** - * 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 - * @format - */ - -import {ConfigCache} from '../ConfigCache'; -import nuclideUri from '../nuclideUri'; - -const CONFIG_FILE_NAME = '.test_nuclide_config_file'; -const CONFIG_FILE_NAME_2 = '.test_nuclide_config_file_2'; - -describe('ConfigCache', () => { - const noConfigFolder = nuclideUri.join(__dirname, 'fixtures'); - const rootFolder = nuclideUri.join(__dirname, 'fixtures/ConfigCache'); - const rootFile = nuclideUri.join(__dirname, 'fixtures/ConfigCache/file'); - const nestedFolder = nuclideUri.join( - __dirname, - 'fixtures/ConfigCache/testFolder', - ); - const nestedFolder2 = nuclideUri.join( - __dirname, - 'fixtures/ConfigCache/testFolder2', - ); - const nestedFile = nuclideUri.join( - __dirname, - 'fixtures/ConfigCache/testFolder/file', - ); +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _ConfigCache; + + + + + + + + + + + +function _load_ConfigCache() {return _ConfigCache = require('../ConfigCache');}var _nuclideUri; +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('../nuclideUri'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */const CONFIG_FILE_NAME = '.test_nuclide_config_file';const CONFIG_FILE_NAME_2 = '.test_nuclide_config_file_2';describe('ConfigCache', () => {const noConfigFolder = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, 'fixtures');const rootFolder = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, 'fixtures/ConfigCache');const rootFile = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, 'fixtures/ConfigCache/file');const nestedFolder = (_nuclideUri || _load_nuclideUri()).default.join(__dirname, + 'fixtures/ConfigCache/testFolder'); + + const nestedFolder2 = (_nuclideUri || _load_nuclideUri()).default.join( + __dirname, + 'fixtures/ConfigCache/testFolder2'); + + const nestedFile = (_nuclideUri || _load_nuclideUri()).default.join( + __dirname, + 'fixtures/ConfigCache/testFolder/file'); + it('finds the right config dir', () => { - waitsForPromise(async () => { - const cache = new ConfigCache([CONFIG_FILE_NAME]); - - expect(await cache.getConfigDir(noConfigFolder)).toBe(null); - expect(await cache.getConfigDir(rootFolder)).toBe(rootFolder); - expect(await cache.getConfigDir(rootFile)).toBe(rootFolder); - expect(await cache.getConfigDir(nestedFolder)).toBe(nestedFolder); - expect(await cache.getConfigDir(nestedFile)).toBe(nestedFolder); - }); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const cache = new (_ConfigCache || _load_ConfigCache()).ConfigCache([CONFIG_FILE_NAME]); + + expect((yield cache.getConfigDir(noConfigFolder))).toBe(null); + expect((yield cache.getConfigDir(rootFolder))).toBe(rootFolder); + expect((yield cache.getConfigDir(rootFile))).toBe(rootFolder); + expect((yield cache.getConfigDir(nestedFolder))).toBe(nestedFolder); + expect((yield cache.getConfigDir(nestedFile))).toBe(nestedFolder); + })); }); it('prefers closer matches with multiple config files', () => { - waitsForPromise(async () => { - const cache = new ConfigCache([CONFIG_FILE_NAME, CONFIG_FILE_NAME_2]); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const cache = new (_ConfigCache || _load_ConfigCache()).ConfigCache([CONFIG_FILE_NAME, CONFIG_FILE_NAME_2]); - expect(await cache.getConfigDir(rootFolder)).toBe(rootFolder); - expect(await cache.getConfigDir(nestedFolder2)).toBe(nestedFolder2); - }); + expect((yield cache.getConfigDir(rootFolder))).toBe(rootFolder); + expect((yield cache.getConfigDir(nestedFolder2))).toBe(nestedFolder2); + })); }); it('prefers further matches when the search strategy is "furthest"', () => { - waitsForPromise(async () => { - const cache = new ConfigCache( - [CONFIG_FILE_NAME, CONFIG_FILE_NAME_2], - 'furthest', - ); - - expect(await cache.getConfigDir(rootFolder)).toBe(rootFolder); - expect(await cache.getConfigDir(nestedFolder)).toBe(rootFolder); - expect(await cache.getConfigDir(nestedFolder2)).toBe(rootFolder); - }); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const cache = new (_ConfigCache || _load_ConfigCache()).ConfigCache( + [CONFIG_FILE_NAME, CONFIG_FILE_NAME_2], + 'furthest'); + + + expect((yield cache.getConfigDir(rootFolder))).toBe(rootFolder); + expect((yield cache.getConfigDir(nestedFolder))).toBe(rootFolder); + expect((yield cache.getConfigDir(nestedFolder2))).toBe(rootFolder); + })); }); it('prefers priority matches when the search strategy is "priority"', () => { - waitsForPromise(async () => { - const cache = new ConfigCache( - [CONFIG_FILE_NAME, CONFIG_FILE_NAME_2], - 'priority', - ); - - expect(await cache.getConfigDir(rootFolder)).toBe(rootFolder); - expect(await cache.getConfigDir(nestedFolder2)).toBe(rootFolder); - }); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const cache = new (_ConfigCache || _load_ConfigCache()).ConfigCache( + [CONFIG_FILE_NAME, CONFIG_FILE_NAME_2], + 'priority'); + + + expect((yield cache.getConfigDir(rootFolder))).toBe(rootFolder); + expect((yield cache.getConfigDir(nestedFolder2))).toBe(rootFolder); + })); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/spec/Hasher-spec.js b/modules/nuclide-commons/spec/Hasher-spec.js index 8135f1c1..b75ab529 100644 --- a/modules/nuclide-commons/spec/Hasher-spec.js +++ b/modules/nuclide-commons/spec/Hasher-spec.js @@ -1,46 +1,56 @@ -/** - * 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 - * @format - */ - -import Hasher from '../Hasher'; +'use strict';var _Hasher; + + + + + + + + + + + +function _load_Hasher() {return _Hasher = _interopRequireDefault(require('../Hasher'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} describe('Hasher', () => { it('creates a new hash for each object', () => { const a = {}; const b = {}; - const hasher = new Hasher(); + const hasher = new (_Hasher || _load_Hasher()).default(); expect(hasher.getHash(a)).not.toBe(hasher.getHash(b)); }); it('returns the same hash for the same object', () => { const a = {}; - const hasher = new Hasher(); + const hasher = new (_Hasher || _load_Hasher()).default(); expect(hasher.getHash(a)).toBe(hasher.getHash(a)); }); it('works for numbers', () => { - const hasher = new Hasher(); + const hasher = new (_Hasher || _load_Hasher()).default(); expect(hasher.getHash(1)).toBe(hasher.getHash(1)); expect(hasher.getHash(1)).not.toBe(hasher.getHash(2)); }); it('works for booleans', () => { - const hasher = new Hasher(); + const hasher = new (_Hasher || _load_Hasher()).default(); expect(hasher.getHash(true)).toBe(hasher.getHash(true)); expect(hasher.getHash(true)).not.toBe(hasher.getHash(false)); }); it('works for strings', () => { - const hasher = new Hasher(); + const hasher = new (_Hasher || _load_Hasher()).default(); expect(hasher.getHash('a')).toBe(hasher.getHash('a')); expect(hasher.getHash('a')).not.toBe(hasher.getHash('b')); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/spec/Model-spec.js b/modules/nuclide-commons/spec/Model-spec.js index 5aed62cc..058ad660 100644 --- a/modules/nuclide-commons/spec/Model-spec.js +++ b/modules/nuclide-commons/spec/Model-spec.js @@ -1,43 +1,53 @@ -/** - * 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 - * @format - */ - -import Model from '../Model'; +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _Model; + + + + + + + + + + + +function _load_Model() {return _Model = _interopRequireDefault(require('../Model'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} describe('Model', () => { it('setStates state when setState is called', () => { - const model = new Model({count: 0, other: true}); - model.setState({count: 5}); + const model = new (_Model || _load_Model()).default({ count: 0, other: true }); + model.setState({ count: 5 }); expect(model.state.count).toBe(5); }); it('only changes the provided values when setState is called', () => { - const model = new Model({count: 0, other: true}); - model.setState({count: 5}); + const model = new (_Model || _load_Model()).default({ count: 0, other: true }); + model.setState({ count: 5 }); expect(model.state.other).toBe(true); }); it('can be converted to an observable', () => { - waitsForPromise(async () => { - const model = new Model({count: 0, other: true}); - const states = model - .toObservable() - .take(2) - .toArray() - .toPromise(); - model.setState({count: 5}); - expect(await states).toEqual([ - {count: 0, other: true}, - {count: 5, other: true}, - ]); - }); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const model = new (_Model || _load_Model()).default({ count: 0, other: true }); + const states = model. + toObservable(). + take(2). + toArray(). + toPromise(); + model.setState({ count: 5 }); + expect((yield states)).toEqual([ + { count: 0, other: true }, + { count: 5, other: true }]); + + })); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/spec/ObservablePool-spec.js b/modules/nuclide-commons/spec/ObservablePool-spec.js index 996b7fe1..091ee918 100644 --- a/modules/nuclide-commons/spec/ObservablePool-spec.js +++ b/modules/nuclide-commons/spec/ObservablePool-spec.js @@ -1,34 +1,34 @@ -/** - * 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 - * @format - */ - -import invariant from 'assert'; -import {Observable, Subject} from 'rxjs'; -import ObservablePool from '../ObservablePool'; +'use strict'; + + + + + + + + + + + + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _ObservablePool; +function _load_ObservablePool() {return _ObservablePool = _interopRequireDefault(require('../ObservablePool'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} describe('ObservablePool', () => { it('limits the concurrency of observable values with cancellation', () => { - const pool = new ObservablePool(2); + const pool = new (_ObservablePool || _load_ObservablePool()).default(2); - const subject1 = new Subject(); + const subject1 = new _rxjsBundlesRxMinJs.Subject(); const spy1 = jasmine.createSpy('1').andReturn(subject1); const req1 = pool.schedule(spy1); - const subject2 = new Subject(); + const subject2 = new _rxjsBundlesRxMinJs.Subject(); const spy2 = jasmine.createSpy('2').andReturn(subject2); const req2 = pool.schedule(spy2); - const subject3 = new Subject(); + const subject3 = new _rxjsBundlesRxMinJs.Subject(); const spy3 = jasmine.createSpy('3').andReturn(subject3); - const req3 = pool.schedule(Observable.defer(spy3)); + const req3 = pool.schedule(_rxjsBundlesRxMinJs.Observable.defer(spy3)); // Nothing should happen until subscription. expect(spy1).not.toHaveBeenCalled(); @@ -61,19 +61,19 @@ describe('ObservablePool', () => { }); it('waits for promises, even on unsubscribe', () => { - const pool = new ObservablePool(1); - let resolve: ?Function; - let reject: ?Function; + const pool = new (_ObservablePool || _load_ObservablePool()).default(1); + let resolve; + let reject; const spy1 = jasmine.createSpy('1').andReturn( - new Promise(r => { - resolve = r; - }), - ); + new Promise(r => { + resolve = r; + })); + const spy2 = jasmine.createSpy('2').andReturn( - new Promise((_, r) => { - reject = r; - }), - ); + new Promise((_, r) => { + reject = r; + })); + const errorSpy = jasmine.createSpy('errorSpy'); const sub1 = pool.schedule(spy1).subscribe(); pool.schedule(spy2).subscribe(() => {}, errorSpy); @@ -81,10 +81,10 @@ describe('ObservablePool', () => { // Immediately subscribe & unsubscribe - // the request should never be scheduled. const spy3 = jasmine.createSpy('3').andReturn(Promise.resolve()); - pool - .schedule(spy3) - .subscribe() - .unsubscribe(); + pool. + schedule(spy3). + subscribe(). + unsubscribe(); expect(spy1).toHaveBeenCalled(); expect(spy2).not.toHaveBeenCalled(); @@ -92,15 +92,15 @@ describe('ObservablePool', () => { sub1.unsubscribe(); // Remove the request, but remain blocked until the promise actually resolves. expect(pool._responseListeners.size).toEqual(1); - expect(spy2).not.toHaveBeenCalled(); - invariant(resolve != null, 'spy1 should have been scheduled'); + expect(spy2).not.toHaveBeenCalled();if (!( + resolve != null)) {throw new Error('spy1 should have been scheduled');} resolve(); // Promise resolution is always async... waitsFor(() => spy2.wasCalled, 'spy2 should be called'); - runs(() => { - invariant(reject != null, 'spy2 was called'); + runs(() => {if (!( + reject != null)) {throw new Error('spy2 was called');} reject('test'); }); @@ -114,25 +114,35 @@ describe('ObservablePool', () => { }); it('catches executor errors', () => { - const pool = new ObservablePool(1); + const pool = new (_ObservablePool || _load_ObservablePool()).default(1); let error; - pool - .schedule(() => { - throw Error('test'); - }) - .subscribe({ - error(err) { - error = err; - }, - }); + pool. + schedule(() => { + throw Error('test'); + }). + subscribe({ + error(err) { + error = err; + } }); + expect(error).toEqual(Error('test')); }); it('errors on disposal', () => { - const pool = new ObservablePool(1); + const pool = new (_ObservablePool || _load_ObservablePool()).default(1); const errorSpy = jasmine.createSpy('errorSpy'); - pool.schedule(() => Promise.resolve()).subscribe({error: errorSpy}); + pool.schedule(() => Promise.resolve()).subscribe({ error: errorSpy }); pool.dispose(); expect(errorSpy).toHaveBeenCalled(); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/spec/SafeStreamMessageReader-spec.js b/modules/nuclide-commons/spec/SafeStreamMessageReader-spec.js index 126e3e15..77e9d672 100644 --- a/modules/nuclide-commons/spec/SafeStreamMessageReader-spec.js +++ b/modules/nuclide-commons/spec/SafeStreamMessageReader-spec.js @@ -1,46 +1,46 @@ -/** - * 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 - * @format - */ - -import Stream from 'stream'; -import SafeStreamMessageReader from '../SafeStreamMessageReader'; - -describe('SafeStreamMessageReader', () => { - it('reads valid messages', () => { - const readable = new Stream.Readable({ - read() { - this.push('Content-Length: 7\r\n\r\n{"a":1}'); - this.push(null); - }, - }); - const reader = new SafeStreamMessageReader(readable); +'use strict'; + + + + + + + + + + + +var _stream = _interopRequireDefault(require('stream'));var _SafeStreamMessageReader; +function _load_SafeStreamMessageReader() {return _SafeStreamMessageReader = _interopRequireDefault(require('../SafeStreamMessageReader'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */describe('SafeStreamMessageReader', () => {it('reads valid messages', () => {const readable = new _stream.default.Readable({ read() {this.push('Content-Length: 7\r\n\r\n{"a":1}');this.push(null);} });const reader = new (_SafeStreamMessageReader || _load_SafeStreamMessageReader()).default(readable); const listenSpy = jasmine.createSpy('listen'); reader.listen(listenSpy); waitsFor(() => listenSpy.wasCalled); runs(() => { - expect(listenSpy.calls[0].args).toEqual([{a: 1}]); + expect(listenSpy.calls[0].args).toEqual([{ a: 1 }]); }); }); it('emits an error for an invalid header', () => { - const readable = new Stream.Readable({ + const readable = new _stream.default.Readable({ read() { this.push('Invalid-Header: test\r\n\r\n'); this.push('Content-Length: 2\r\n\r\n{}'); this.push(null); - }, - }); - const reader = new SafeStreamMessageReader(readable); + } }); + + const reader = new (_SafeStreamMessageReader || _load_SafeStreamMessageReader()).default(readable); const listenSpy = jasmine.createSpy('listen'); const errorSpy = jasmine.createSpy('error'); reader.listen(listenSpy); @@ -53,4 +53,4 @@ describe('SafeStreamMessageReader', () => { expect(listenSpy).not.toHaveBeenCalled(); }); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/spec/UniversalDisposable-spec.js b/modules/nuclide-commons/spec/UniversalDisposable-spec.js index f3f0744f..f3061264 100644 --- a/modules/nuclide-commons/spec/UniversalDisposable-spec.js +++ b/modules/nuclide-commons/spec/UniversalDisposable-spec.js @@ -1,21 +1,21 @@ -/** - * 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 - * @format - */ - -import UniversalDisposable from '../UniversalDisposable'; +'use strict';var _UniversalDisposable; + + + + + + + + + + + +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('../UniversalDisposable'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} describe('UniversalDisposable', () => { it('disposes of the Disposable arguments', () => { const dispose = jasmine.createSpy('dispose'); - const universal = new UniversalDisposable({dispose}); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default({ dispose }); expect(dispose.wasCalled).toBe(false); universal.dispose(); @@ -23,7 +23,7 @@ describe('UniversalDisposable', () => { }); it('throws if you add after disposing', () => { - const universal = new UniversalDisposable(); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default(); universal.dispose(); expect(() => { universal.add(() => {}); @@ -32,7 +32,7 @@ describe('UniversalDisposable', () => { it('calls function arguments', () => { const foo = jasmine.createSpy('foo'); - const universal = new UniversalDisposable(foo); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default(foo); expect(foo.wasCalled).toBe(false); universal.dispose(); @@ -41,7 +41,7 @@ describe('UniversalDisposable', () => { it('calls unsubscribe arguments', () => { const unsubscribe = jasmine.createSpy('unsubscribe'); - const universal = new UniversalDisposable(unsubscribe); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default(unsubscribe); expect(unsubscribe.wasCalled).toBe(false); universal.dispose(); @@ -52,7 +52,7 @@ describe('UniversalDisposable', () => { const dispose = jasmine.createSpy('dispose'); const unsubscribe = jasmine.createSpy('unsubscribe'); const foo = jasmine.createSpy('foo'); - const universal = new UniversalDisposable({dispose}, {unsubscribe}, foo); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default({ dispose }, { unsubscribe }, foo); expect(dispose.wasCalled).toBe(false); expect(unsubscribe.wasCalled).toBe(false); @@ -67,8 +67,8 @@ describe('UniversalDisposable', () => { const dispose = jasmine.createSpy('dispose'); const unsubscribe = jasmine.createSpy('unsubscribe'); const foo = jasmine.createSpy('foo'); - const universal = new UniversalDisposable(); - universal.add({dispose}, {unsubscribe}, foo); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default(); + universal.add({ dispose }, { unsubscribe }, foo); expect(dispose.wasCalled).toBe(false); expect(unsubscribe.wasCalled).toBe(false); @@ -83,7 +83,7 @@ describe('UniversalDisposable', () => { const dispose = jasmine.createSpy('dispose'); const unsubscribe = jasmine.createSpy('unsubscribe'); const foo = jasmine.createSpy('foo'); - const universal = new UniversalDisposable({dispose}, {unsubscribe}, foo); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default({ dispose }, { unsubscribe }, foo); expect(dispose.wasCalled).toBe(false); expect(unsubscribe.wasCalled).toBe(false); @@ -98,7 +98,7 @@ describe('UniversalDisposable', () => { const dispose = jasmine.createSpy('dispose'); const unsubscribe = jasmine.createSpy('unsubscribe'); const foo = jasmine.createSpy('foo'); - const universal = new UniversalDisposable({dispose}, {unsubscribe}, foo); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default({ dispose }, { unsubscribe }, foo); expect(dispose.wasCalled).toBe(false); expect(unsubscribe.wasCalled).toBe(false); @@ -113,10 +113,10 @@ describe('UniversalDisposable', () => { }); it('supports removal of the teardowns', () => { - const dispose = {dispose: jasmine.createSpy('dispose')}; - const unsubscribe = {unsubscribe: jasmine.createSpy('unsubscribe')}; + const dispose = { dispose: jasmine.createSpy('dispose') }; + const unsubscribe = { unsubscribe: jasmine.createSpy('unsubscribe') }; const foo = jasmine.createSpy('foo'); - const universal = new UniversalDisposable(dispose, unsubscribe, foo); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default(dispose, unsubscribe, foo); universal.remove(unsubscribe); universal.remove(dispose); @@ -130,10 +130,10 @@ describe('UniversalDisposable', () => { }); it('can clear all of the teardowns', () => { - const dispose = {dispose: jasmine.createSpy('dispose')}; - const unsubscribe = {unsubscribe: jasmine.createSpy('unsubscribe')}; + const dispose = { dispose: jasmine.createSpy('dispose') }; + const unsubscribe = { unsubscribe: jasmine.createSpy('unsubscribe') }; const foo = jasmine.createSpy('foo'); - const universal = new UniversalDisposable(dispose, unsubscribe, foo); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default(dispose, unsubscribe, foo); universal.clear(); @@ -152,7 +152,7 @@ describe('UniversalDisposable', () => { const foo3 = () => ids.push(3); const foo4 = () => ids.push(4); - const universal = new UniversalDisposable(foo1, foo3); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default(foo1, foo3); universal.add(foo4, foo2); universal.dispose(); @@ -162,11 +162,11 @@ describe('UniversalDisposable', () => { describe('teardown priority', () => { it('calls dispose()', () => { - const foo: Function = jasmine.createSpy('foo'); + const foo = jasmine.createSpy('foo'); foo.dispose = jasmine.createSpy('dispose'); foo.unsubscribe = jasmine.createSpy('unsubscribe'); - const universal = new UniversalDisposable(foo); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default(foo); universal.dispose(); expect(foo.dispose.wasCalled).toBe(true); @@ -175,11 +175,11 @@ describe('UniversalDisposable', () => { }); it('calls unsubscribe()', () => { - const foo: Function = jasmine.createSpy('foo'); + const foo = jasmine.createSpy('foo'); foo.dispose = null; foo.unsubscribe = jasmine.createSpy('unsubscribe'); - const universal = new UniversalDisposable(foo); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default(foo); universal.dispose(); expect(foo.unsubscribe.wasCalled).toBe(true); @@ -187,14 +187,24 @@ describe('UniversalDisposable', () => { }); it('calls the function', () => { - const foo: Function = jasmine.createSpy('foo'); + const foo = jasmine.createSpy('foo'); foo.dispose = null; foo.unsubscribe = null; - const universal = new UniversalDisposable(foo); + const universal = new (_UniversalDisposable || _load_UniversalDisposable()).default(foo); universal.dispose(); expect(foo.wasCalled).toBe(true); }); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/spec/cache-spec.js b/modules/nuclide-commons/spec/cache-spec.js index f97010d4..26fa4033 100644 --- a/modules/nuclide-commons/spec/cache-spec.js +++ b/modules/nuclide-commons/spec/cache-spec.js @@ -1,16 +1,16 @@ -/** - * 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 - * @format - */ - -import {Cache} from '../cache'; +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _cache; + + + + + + + + + + + +function _load_cache() {return _cache = require('../cache');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} describe('Cache', () => { const key1 = 'key1'; @@ -24,7 +24,7 @@ describe('Cache', () => { expect(key).toEqual(key1); return value; }); - const cache: Cache = new Cache(factory); + const cache = new (_cache || _load_cache()).Cache(factory); expect(factory).not.toHaveBeenCalled(); expect(cache.has(key1)).toEqual(false); @@ -40,7 +40,7 @@ describe('Cache', () => { it('delete', () => { const factory = jasmine.createSpy('factory').andReturn(value); - const cache: Cache = new Cache(factory); + const cache = new (_cache || _load_cache()).Cache(factory); expect(cache.delete(key1)).toEqual(false); cache.get(key1); @@ -52,7 +52,7 @@ describe('Cache', () => { it('delete disposes values', () => { const factory = jasmine.createSpy('factory').andReturn(value); const dispose = jasmine.createSpy('dispose'); - const cache: Cache = new Cache(factory, dispose); + const cache = new (_cache || _load_cache()).Cache(factory, dispose); cache.get(key1); cache.delete(key1); @@ -62,7 +62,7 @@ describe('Cache', () => { it('clear disposes values', () => { const factory = jasmine.createSpy('factory').andReturn(value); const dispose = jasmine.createSpy('dispose'); - const cache: Cache = new Cache(factory, dispose); + const cache = new (_cache || _load_cache()).Cache(factory, dispose); cache.get(key1); cache.clear(); @@ -72,7 +72,7 @@ describe('Cache', () => { it('dispose disposes values', () => { const factory = jasmine.createSpy('factory').andReturn(value); const dispose = jasmine.createSpy('dispose'); - const cache: Cache = new Cache(factory, dispose); + const cache = new (_cache || _load_cache()).Cache(factory, dispose); cache.get(key1); cache.dispose(); @@ -80,34 +80,44 @@ describe('Cache', () => { }); it('observeValues sees existing and new values', () => { - waitsForPromise(async () => { - const factory = jasmine.createSpy('factory').andCallFake(key => key); - const cache: Cache = new Cache(factory); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const factory = jasmine.createSpy('factory').andCallFake(function (key) {return key;}); + const cache = new (_cache || _load_cache()).Cache(factory); cache.get(key1); - const values = cache - .observeValues() - .toArray() - .toPromise(); + const values = cache. + observeValues(). + toArray(). + toPromise(); cache.get(key2); cache.dispose(); - expect(await values).toEqual([key1, key2]); - }); + expect((yield values)).toEqual([key1, key2]); + })); }); it('observeKeys sees existing and new keys', () => { - waitsForPromise(async () => { - const factory = jasmine.createSpy('factory').andCallFake(key => value); - const cache: Cache = new Cache(factory); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const factory = jasmine.createSpy('factory').andCallFake(function (key) {return value;}); + const cache = new (_cache || _load_cache()).Cache(factory); cache.get(key1); - const values = cache - .observeKeys() - .toArray() - .toPromise(); + const values = cache. + observeKeys(). + toArray(). + toPromise(); cache.get(key2); cache.dispose(); - expect(await values).toEqual([key1, key2]); - }); + expect((yield values)).toEqual([key1, key2]); + })); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/spec/collection-spec.js b/modules/nuclide-commons/spec/collection-spec.js index 6c05e87a..da7bc3ee 100644 --- a/modules/nuclide-commons/spec/collection-spec.js +++ b/modules/nuclide-commons/spec/collection-spec.js @@ -1,155 +1,155 @@ -/** - * 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 - * @format - */ - -import { - ensureArray, - arrayRemove, - arrayEqual, - arrayCompact, - arrayFindLastIndex, - mapUnion, - insideOut, - isEmpty, - isIterable, - keyMirror, - setFilter, - setIntersect, - setUnion, - collect, - DefaultMap, - MultiMap, - objectEntries, - objectFromPairs, - objectFromMap, - objectMapValues, - objectValues, - concatIterators, - areSetsEqual, - someOfIterable, - findInIterable, - filterIterable, - mapEqual, - mapIterable, - mapGetWithDefault, - count, - range, - mapFromObject, - distinct, - takeIterable, -} from '../collection'; +'use strict';var _collection; + + + + + + + + + + + +function _load_collection() {return _collection = require('../collection');} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + describe('ensureArray', () => { it('works on arrays', () => { - expect(ensureArray([1])).toEqual([1]); - expect(ensureArray(['test'])).toEqual(['test']); + expect((0, (_collection || _load_collection()).ensureArray)([1])).toEqual([1]); + expect((0, (_collection || _load_collection()).ensureArray)(['test'])).toEqual(['test']); }); it('works on non-arrays', () => { - expect(ensureArray(1)).toEqual([1]); - expect(ensureArray('test')).toEqual(['test']); - }); -}); - -describe('arrayRemove', () => { - let a: any; - let empty: any; - let single: any; - - beforeEach(() => { - a = ['a', 'b', 'c']; - empty = []; - single = ['x']; + expect((0, (_collection || _load_collection()).ensureArray)(1)).toEqual([1]); + expect((0, (_collection || _load_collection()).ensureArray)('test')).toEqual(['test']); + }); +}); /** + * 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. + * + * + * @format + */describe('arrayRemove', () => {let a;let empty;let single;beforeEach(() => {a = ['a', 'b', 'c'];empty = [];single = ['x']; }); it('removes an element properly', () => { - arrayRemove(a, 'b'); + (0, (_collection || _load_collection()).arrayRemove)(a, 'b'); expect(a).toEqual(['a', 'c']); }); it('removes the first element properly', () => { - arrayRemove(a, 'a'); + (0, (_collection || _load_collection()).arrayRemove)(a, 'a'); expect(a).toEqual(['b', 'c']); }); it('removes the last element properly', () => { - arrayRemove(a, 'c'); + (0, (_collection || _load_collection()).arrayRemove)(a, 'c'); expect(a).toEqual(['a', 'b']); }); it('does nothing if the element is not found', () => { - arrayRemove(a, 'd'); + (0, (_collection || _load_collection()).arrayRemove)(a, 'd'); expect(a).toEqual(['a', 'b', 'c']); }); it('does nothing to an empty array', () => { - arrayRemove(empty, 'a'); + (0, (_collection || _load_collection()).arrayRemove)(empty, 'a'); expect(empty).toEqual([]); }); it('works when there is a single element', () => { - arrayRemove(single, 'x'); + (0, (_collection || _load_collection()).arrayRemove)(single, 'x'); expect(single).toEqual([]); }); }); describe('arrayEqual', () => { it('checks boolean elements', () => { - expect(arrayEqual([true, false, true], [true, false, true])).toBe(true); - expect(arrayEqual([true], [false])).toBe(false); + expect((0, (_collection || _load_collection()).arrayEqual)([true, false, true], [true, false, true])).toBe(true); + expect((0, (_collection || _load_collection()).arrayEqual)([true], [false])).toBe(false); }); it('checks number elements', () => { - expect(arrayEqual([1, 2, 3], [1, 2, 3])).toBe(true); - expect(arrayEqual([1, 5, 3], [1, 2, 3])).toBe(false); + expect((0, (_collection || _load_collection()).arrayEqual)([1, 2, 3], [1, 2, 3])).toBe(true); + expect((0, (_collection || _load_collection()).arrayEqual)([1, 5, 3], [1, 2, 3])).toBe(false); }); it('checks object elements', () => { - expect(arrayEqual([{}], [{}])).toBe(false); + expect((0, (_collection || _load_collection()).arrayEqual)([{}], [{}])).toBe(false); expect( - arrayEqual([{x: 1}, {x: 2}], [{x: 1}, {x: 2}], (a, b) => a.x === b.x), - ).toBe(true); + (0, (_collection || _load_collection()).arrayEqual)([{ x: 1 }, { x: 2 }], [{ x: 1 }, { x: 2 }], (a, b) => a.x === b.x)). + toBe(true); }); it('works with arrays of different lengths', () => { - expect(arrayEqual([1, 2], [1, 2, 3])).toBe(false); - expect(arrayEqual([1, 2, 3], [1, 2])).toBe(false); + expect((0, (_collection || _load_collection()).arrayEqual)([1, 2], [1, 2, 3])).toBe(false); + expect((0, (_collection || _load_collection()).arrayEqual)([1, 2, 3], [1, 2])).toBe(false); }); it("doesn't call the compare function if the same array is used", () => { const compare = jasmine.createSpy().andReturn(true); const a = [1, 2, 3]; - arrayEqual(a, a, compare); + (0, (_collection || _load_collection()).arrayEqual)(a, a, compare); expect(compare).not.toHaveBeenCalled(); }); }); describe('arrayCompact', () => { it('filters out null and undefined elements', () => { - expect(arrayCompact([0, false, '', [], null, undefined])).toEqual([ - 0, - false, - '', - [], - ]); + expect((0, (_collection || _load_collection()).arrayCompact)([0, false, '', [], null, undefined])).toEqual([ + 0, + false, + '', + []]); + }); }); describe('arrayFindLastIndex', () => { it('returns the last matching index', () => { - expect(arrayFindLastIndex([1, 1, 2], x => x === 1)).toBe(1); + expect((0, (_collection || _load_collection()).arrayFindLastIndex)([1, 1, 2], x => x === 1)).toBe(1); }); it('returns -1 if no match is found', () => { - expect(arrayFindLastIndex([1, 1, 2], x => x === 0)).toBe(-1); + expect((0, (_collection || _load_collection()).arrayFindLastIndex)([1, 1, 2], x => x === 0)).toBe(-1); }); }); @@ -157,7 +157,7 @@ describe('mapUnion', () => { it('merges two unique maps', () => { const map1 = new Map([['key1', 'value1'], ['key2', 'value2']]); const map2 = new Map([['key3', 'value3'], ['key4', 'value4']]); - const result = mapUnion(map1, map2); + const result = (0, (_collection || _load_collection()).mapUnion)(map1, map2); expect(result.size).toBe(4); expect(result.get('key1')).toBe('value1'); @@ -169,7 +169,7 @@ describe('mapUnion', () => { it('overrodes with the values of the latest maps', () => { const map1 = new Map([['commonKey', 'value1'], ['key2', 'value2']]); const map2 = new Map([['commonKey', 'value3'], ['key4', 'value4']]); - const result = mapUnion(...[map1, map2]); + const result = (0, (_collection || _load_collection()).mapUnion)(...[map1, map2]); expect(result.size).toBe(3); expect(result.get('commonKey')).toBe('value3'); @@ -180,31 +180,31 @@ describe('mapUnion', () => { describe('isEmpty', () => { it('correctly identifies empty Objects', () => { - expect(isEmpty({})).toEqual(true); + expect((0, (_collection || _load_collection()).isEmpty)({})).toEqual(true); }); it('correctly identifies non-empty Objects', () => { - const proto = {a: 1, b: 2, c: 3}; - const objWithOwnProperties = Object.create(proto, {foo: {value: 'bar'}}); + const proto = { a: 1, b: 2, c: 3 }; + const objWithOwnProperties = Object.create(proto, { foo: { value: 'bar' } }); const objWithoutOwnProperties = Object.create(proto); - expect(isEmpty({a: 1})).toEqual(false); - expect(isEmpty(objWithOwnProperties)).toEqual(false); - expect(isEmpty(objWithoutOwnProperties)).toEqual(false); + expect((0, (_collection || _load_collection()).isEmpty)({ a: 1 })).toEqual(false); + expect((0, (_collection || _load_collection()).isEmpty)(objWithOwnProperties)).toEqual(false); + expect((0, (_collection || _load_collection()).isEmpty)(objWithoutOwnProperties)).toEqual(false); }); }); describe('isIterable', () => { it('detects arrays are iterable', () => { - expect(isIterable(['foo', 'bar'])).toBe(true); + expect((0, (_collection || _load_collection()).isIterable)(['foo', 'bar'])).toBe(true); }); it('detects strings are iterable', () => { - expect(isIterable('foo')).toBe(true); + expect((0, (_collection || _load_collection()).isIterable)('foo')).toBe(true); }); it('detects Sets are iterable', () => { - expect(isIterable(new Set(['foo', 'bar']))).toBe(true); + expect((0, (_collection || _load_collection()).isIterable)(new Set(['foo', 'bar']))).toBe(true); }); it('detects iterable objects are iterable', () => { @@ -212,31 +212,31 @@ describe('isIterable', () => { *[Symbol.iterator]() { yield 1; yield 42; - }, - }; + } }; - expect(isIterable(anIterable)).toBe(true); + + expect((0, (_collection || _load_collection()).isIterable)(anIterable)).toBe(true); }); it('detects plain objects are not iterable', () => { - expect(isIterable({foo: 'bar', baz: 42})).toBe(false); + expect((0, (_collection || _load_collection()).isIterable)({ foo: 'bar', baz: 42 })).toBe(false); }); it('detects numbers are not iterable', () => { - expect(isIterable(42)).toBe(false); + expect((0, (_collection || _load_collection()).isIterable)(42)).toBe(false); }); }); describe('keyMirror', () => { it('correctly mirrors objects', () => { - expect(keyMirror({a: null, b: null})).toEqual({a: 'a', b: 'b'}); + expect((0, (_collection || _load_collection()).keyMirror)({ a: null, b: null })).toEqual({ a: 'a', b: 'b' }); }); }); describe('setFilter', () => { it('filters', () => { const set = new Set(['foo', 'bar', 'baz']); - const filtered = setFilter(set, x => x.startsWith('b')); + const filtered = (0, (_collection || _load_collection()).setFilter)(set, x => x.startsWith('b')); expect(filtered.size).toBe(2); expect(filtered.has('bar')).toBe(true); @@ -249,7 +249,7 @@ describe('setIntersect', () => { it('intersects', () => { const set1 = new Set(['foo', 'bar', 'baz']); const set2 = new Set(['fool', 'bar', 'bazl']); - const result = setIntersect(set1, set2); + const result = (0, (_collection || _load_collection()).setIntersect)(set1, set2); expect(result.size).toBe(1); expect(result.has('bar')).toBe(true); @@ -260,27 +260,27 @@ describe('setUnion', () => { it('unions', () => { const set1 = new Set(['foo', 'bar', 'baz']); const set2 = new Set(['fool', 'bar', 'bazl']); - const result = setUnion(set1, set2); + const result = (0, (_collection || _load_collection()).setUnion)(set1, set2); const expected = new Set(['foo', 'bar', 'baz', 'fool', 'bazl']); - expect(areSetsEqual(result, expected)).toBe(true); + expect((0, (_collection || _load_collection()).areSetsEqual)(result, expected)).toBe(true); }); }); describe('collect', () => { it('collects key-value pairs into a Map of arrays', () => { const pairs = [ - ['neither', 1], - ['neither', 2], - ['fizz', 3], - ['neither', 4], - ['buzz', 5], - ['fizz', 6], - ['neither', 7], - ['neither', 8], - ['fizz', 9], - ]; - const result = collect(pairs); + ['neither', 1], + ['neither', 2], + ['fizz', 3], + ['neither', 4], + ['buzz', 5], + ['fizz', 6], + ['neither', 7], + ['neither', 8], + ['fizz', 9]]; + + const result = (0, (_collection || _load_collection()).collect)(pairs); expect(result.size).toBe(3); expect(result.get('fizz')).toEqual([3, 6, 9]); @@ -292,7 +292,7 @@ describe('collect', () => { describe('DefaultMap', () => { it('calls the factory each time you get a nonexistant key', () => { const spy = jasmine.createSpy().andReturn('default'); - const map = new DefaultMap(spy); + const map = new (_collection || _load_collection()).DefaultMap(spy); expect(map.size).toBe(0); expect(map.get('a')).toBe('default'); expect(map.get('b')).toBe('default'); @@ -301,7 +301,7 @@ describe('DefaultMap', () => { }); it('can be cleared', () => { - const map = new DefaultMap(() => 'default'); + const map = new (_collection || _load_collection()).DefaultMap(() => 'default'); map.get('a'); map.get('b'); map.clear(); @@ -309,14 +309,14 @@ describe('DefaultMap', () => { }); it('can update default values', () => { - const map = new DefaultMap(() => 'default'); + const map = new (_collection || _load_collection()).DefaultMap(() => 'default'); expect(map.get('a')).toBe('default'); map.set('a', 'custom'); expect(map.get('a')).toBe('custom'); }); it('can be iterated', () => { - const map = new DefaultMap(() => 'default'); + const map = new (_collection || _load_collection()).DefaultMap(() => 'default'); map.get('a'); map.get('b'); expect([...map.keys()]).toEqual(['a', 'b']); @@ -324,7 +324,7 @@ describe('DefaultMap', () => { }); it('takes initial values', () => { - const map = new DefaultMap(() => 0, [['a', 1], ['b', 2]]); + const map = new (_collection || _load_collection()).DefaultMap(() => 0, [['a', 1], ['b', 2]]); map.get('c'); expect([...map.entries()]).toEqual([['a', 1], ['b', 2], ['c', 0]]); expect(map.size).toBe(3); @@ -332,10 +332,10 @@ describe('DefaultMap', () => { }); describe('MultiMap', () => { - let multimap: MultiMap = (null: any); + let multimap = null; beforeEach(() => { - multimap = new MultiMap(); + multimap = new (_collection || _load_collection()).MultiMap(); }); afterEach(() => { @@ -363,10 +363,10 @@ describe('MultiMap', () => { }); it('properly adds multiple bindings', () => { - multimap - .add(1, 2) - .add(1, 3) - .add(10, 11); + multimap. + add(1, 2). + add(1, 3). + add(10, 11); expect(multimap.size).toEqual(3); expect(multimap.get(1)).toEqual(new Set([2, 3])); expect(multimap.get(10)).toEqual(new Set([11])); @@ -379,10 +379,10 @@ describe('MultiMap', () => { }); it('properly deletes a single binding', () => { - multimap - .add(1, 2) - .add(1, 3) - .add(10, 11); + multimap. + add(1, 2). + add(1, 3). + add(10, 11); expect(multimap.delete(1, 2)).toBe(true); expect(multimap.get(1)).toEqual(new Set([3])); expect(multimap.get(10)).toEqual(new Set([11])); @@ -401,10 +401,10 @@ describe('MultiMap', () => { }); it('properly clears', () => { - multimap - .add(1, 2) - .add(1, 3) - .add(10, 11); + multimap. + add(1, 2). + add(1, 3). + add(10, 11); multimap.clear(); expect(multimap.size).toEqual(0); expect(multimap.get(1)).toEqual(new Set()); @@ -428,270 +428,270 @@ describe('MultiMap', () => { describe('objectValues', () => { it('returns the values of an object', () => { expect( - objectValues({ - a: 1, - b: 2, - c: 4, - }), - ).toEqual([1, 2, 4]); + (0, (_collection || _load_collection()).objectValues)({ + a: 1, + b: 2, + c: 4 })). + + toEqual([1, 2, 4]); }); it('throws for null', () => { - expect(() => objectEntries(null)).toThrow(); + expect(() => (0, (_collection || _load_collection()).objectEntries)(null)).toThrow(); }); it('throws for undefined', () => { - expect(() => objectEntries(undefined)).toThrow(); + expect(() => (0, (_collection || _load_collection()).objectEntries)(undefined)).toThrow(); }); }); describe('objectEntries', () => { it('gets the entries of an object', () => { - expect(objectEntries({a: 1, b: 2})).toEqual([['a', 1], ['b', 2]]); + expect((0, (_collection || _load_collection()).objectEntries)({ a: 1, b: 2 })).toEqual([['a', 1], ['b', 2]]); }); it('errors for null', () => { - expect(() => objectEntries((null: any))).toThrow(); + expect(() => (0, (_collection || _load_collection()).objectEntries)(null)).toThrow(); }); it('errors for undefined', () => { - expect(() => objectEntries((null: any))).toThrow(); + expect(() => (0, (_collection || _load_collection()).objectEntries)(null)).toThrow(); }); it('only includes own properties', () => { - const a = {a: 1}; - const b = {b: 2}; + const a = { a: 1 }; + const b = { b: 2 }; Object.setPrototypeOf(b, a); - expect(objectEntries(b)).toEqual([['b', 2]]); + expect((0, (_collection || _load_collection()).objectEntries)(b)).toEqual([['b', 2]]); }); }); describe('objectFromMap', () => { it('converts a map to an object', () => { - expect(objectFromMap(new Map([['a', 1], ['b', 2]]))).toEqual({a: 1, b: 2}); + expect((0, (_collection || _load_collection()).objectFromMap)(new Map([['a', 1], ['b', 2]]))).toEqual({ a: 1, b: 2 }); }); }); describe('concatIterators', () => { it('concatenates different iterable stuff to a single iterator', () => { expect( - Array.from( - concatIterators( - new Set([1, 2, 3]), - [4, 5, 6], - new Set([7, 8, 9]).values(), - ), - ), - ).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]); + Array.from( + (0, (_collection || _load_collection()).concatIterators)( + new Set([1, 2, 3]), + [4, 5, 6], + new Set([7, 8, 9]).values()))). + + + toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]); }); }); describe('areSetsEqual', () => { it('correctly compares empty sets', () => { - expect(areSetsEqual(new Set(), new Set())).toBe(true); + expect((0, (_collection || _load_collection()).areSetsEqual)(new Set(), new Set())).toBe(true); }); it('correctly compares sets with the same properties', () => { - expect(areSetsEqual(new Set(['foo']), new Set(['foo']))).toBe(true); + expect((0, (_collection || _load_collection()).areSetsEqual)(new Set(['foo']), new Set(['foo']))).toBe(true); }); it('returns false when properties are not equal', () => { - expect(areSetsEqual(new Set(['foo']), new Set(['bar']))).toBe(false); + expect((0, (_collection || _load_collection()).areSetsEqual)(new Set(['foo']), new Set(['bar']))).toBe(false); }); it('returns false when an item exists in one set but not the other', () => { - expect(areSetsEqual(new Set(['foo']), new Set())).toBe(false); - expect(areSetsEqual(new Set(), new Set(['foo']))).toBe(false); + expect((0, (_collection || _load_collection()).areSetsEqual)(new Set(['foo']), new Set())).toBe(false); + expect((0, (_collection || _load_collection()).areSetsEqual)(new Set(), new Set(['foo']))).toBe(false); }); }); describe('someOfIterable', () => { it('lazily returns whether any element of an iterable fulfills a given predicate', () => { expect( - someOfIterable(new Set([1, 2, 3, 4, 5]), element => element % 2 === 0), - ).toEqual(true); + (0, (_collection || _load_collection()).someOfIterable)(new Set([1, 2, 3, 4, 5]), element => element % 2 === 0)). + toEqual(true); expect( - someOfIterable(new Set([1, 2, 3, 4, 5]), element => element % 5 === 0), - ).toEqual(true); + (0, (_collection || _load_collection()).someOfIterable)(new Set([1, 2, 3, 4, 5]), element => element % 5 === 0)). + toEqual(true); expect( - someOfIterable(new Set([1, 2, 3, 4, 5]), element => element % 6 === 0), - ).toEqual(false); - expect(someOfIterable([], element => true)).toEqual(false); + (0, (_collection || _load_collection()).someOfIterable)(new Set([1, 2, 3, 4, 5]), element => element % 6 === 0)). + toEqual(false); + expect((0, (_collection || _load_collection()).someOfIterable)([], element => true)).toEqual(false); }); }); describe('findInIterable', () => { it('return the first element of an iterable which fulfills a given predicate', () => { expect( - findInIterable(new Set([1, 2, 3, 4, 5]), element => element % 2 === 0), - ).toEqual(2); + (0, (_collection || _load_collection()).findInIterable)(new Set([1, 2, 3, 4, 5]), element => element % 2 === 0)). + toEqual(2); expect( - findInIterable(new Set([1, 2, 3, 4, 5]), element => element % 5 === 0), - ).toEqual(5); + (0, (_collection || _load_collection()).findInIterable)(new Set([1, 2, 3, 4, 5]), element => element % 5 === 0)). + toEqual(5); expect( - findInIterable(new Set([1, 2, 3, 4, 5]), element => element % 6 === 0), - ).toEqual(null); - expect(findInIterable([], element => true)).toEqual(null); + (0, (_collection || _load_collection()).findInIterable)(new Set([1, 2, 3, 4, 5]), element => element % 6 === 0)). + toEqual(null); + expect((0, (_collection || _load_collection()).findInIterable)([], element => true)).toEqual(null); }); }); describe('filterIterable', () => { it('returns a (lazy) iterable containing all elements which fulfill the given predicate', () => { expect( - Array.from( - filterIterable(new Set([1, 2, 3, 4, 5]), element => element % 2 === 0), - ), - ).toEqual([2, 4]); + Array.from( + (0, (_collection || _load_collection()).filterIterable)(new Set([1, 2, 3, 4, 5]), element => element % 2 === 0))). + + toEqual([2, 4]); expect( - Array.from(filterIterable(new Set([1, 2, 3, 4, 5]), element => true)), - ).toEqual([1, 2, 3, 4, 5]); + Array.from((0, (_collection || _load_collection()).filterIterable)(new Set([1, 2, 3, 4, 5]), element => true))). + toEqual([1, 2, 3, 4, 5]); expect( - Array.from(filterIterable(new Set([1, 2, 3, 4, 5]), element => false)), - ).toEqual([]); - expect(Array.from(filterIterable([], element => true))).toEqual([]); + Array.from((0, (_collection || _load_collection()).filterIterable)(new Set([1, 2, 3, 4, 5]), element => false))). + toEqual([]); + expect(Array.from((0, (_collection || _load_collection()).filterIterable)([], element => true))).toEqual([]); }); }); describe('takeIterable', () => { it('returns a (lazy) iterable containing the first n elements', () => { expect( - Array.from(takeIterable(new Set([1, 2, 3, 4, 5]), 3)).length, - ).toEqual(3); - expect(Array.from(takeIterable([1, 2, 3], 0)).length).toEqual(0); - expect(Array.from(takeIterable([1, 2, 3], 1)).length).toEqual(1); - expect(Array.from(takeIterable([1, 2, 3], 2)).length).toEqual(2); - expect(Array.from(takeIterable([1, 2, 3], 3)).length).toEqual(3); - expect(Array.from(takeIterable([1, 2, 3], 4)).length).toEqual(3); + Array.from((0, (_collection || _load_collection()).takeIterable)(new Set([1, 2, 3, 4, 5]), 3)).length). + toEqual(3); + expect(Array.from((0, (_collection || _load_collection()).takeIterable)([1, 2, 3], 0)).length).toEqual(0); + expect(Array.from((0, (_collection || _load_collection()).takeIterable)([1, 2, 3], 1)).length).toEqual(1); + expect(Array.from((0, (_collection || _load_collection()).takeIterable)([1, 2, 3], 2)).length).toEqual(2); + expect(Array.from((0, (_collection || _load_collection()).takeIterable)([1, 2, 3], 3)).length).toEqual(3); + expect(Array.from((0, (_collection || _load_collection()).takeIterable)([1, 2, 3], 4)).length).toEqual(3); }); }); describe('mapEqual', () => { it('checks primary elements', () => { expect( - mapEqual( - new Map([[1, true], [2, false], [5, true]]), - new Map([[1, true], [2, false], [5, true]]), - ), - ).toBe(true); - expect(mapEqual(new Map([[1, true]]), new Map([[1, false]]))).toBe(false); - expect(mapEqual(new Map([[1, true]]), new Map([]))).toBe(false); - expect(mapEqual(new Map([[1, true]]), new Map([[2, false]]))).toBe(false); + (0, (_collection || _load_collection()).mapEqual)( + new Map([[1, true], [2, false], [5, true]]), + new Map([[1, true], [2, false], [5, true]]))). + + toBe(true); + expect((0, (_collection || _load_collection()).mapEqual)(new Map([[1, true]]), new Map([[1, false]]))).toBe(false); + expect((0, (_collection || _load_collection()).mapEqual)(new Map([[1, true]]), new Map([]))).toBe(false); + expect((0, (_collection || _load_collection()).mapEqual)(new Map([[1, true]]), new Map([[2, false]]))).toBe(false); }); it('checks object value elements', () => { - expect(mapEqual(new Map([[1, {x: 1}]]), new Map([[1, {x: 1}]]))).toBe( - false, - ); + expect((0, (_collection || _load_collection()).mapEqual)(new Map([[1, { x: 1 }]]), new Map([[1, { x: 1 }]]))).toBe( + false); + expect( - mapEqual( - new Map([[1, {x: 1}]]), - new Map([[1, {x: 1}]]), - (v1, v2) => v1.x === v2.x, - ), - ).toBe(true); + (0, (_collection || _load_collection()).mapEqual)( + new Map([[1, { x: 1 }]]), + new Map([[1, { x: 1 }]]), + (v1, v2) => v1.x === v2.x)). + + toBe(true); }); }); describe('mapIterable', () => { it('projects each element of an iterable into a new iterable', () => { - expect(Array.from(mapIterable(new Set(), element => true))).toEqual([]); + expect(Array.from((0, (_collection || _load_collection()).mapIterable)(new Set(), element => true))).toEqual([]); expect( - Array.from( - mapIterable(new Set([1, 2, 3, 4, 5]), element => element * element), - ), - ).toEqual([1, 4, 9, 16, 25]); + Array.from( + (0, (_collection || _load_collection()).mapIterable)(new Set([1, 2, 3, 4, 5]), element => element * element))). + + toEqual([1, 4, 9, 16, 25]); }); }); describe('mapGetWithDefault', () => { it('normally returns whatever is in the map', () => { - expect(mapGetWithDefault(new Map([[1, 2]]), 1, 3)).toBe(2); + expect((0, (_collection || _load_collection()).mapGetWithDefault)(new Map([[1, 2]]), 1, 3)).toBe(2); }); it('returns the default if the key is not in the map', () => { - expect(mapGetWithDefault(new Map([[1, 2]]), 5, 3)).toBe(3); + expect((0, (_collection || _load_collection()).mapGetWithDefault)(new Map([[1, 2]]), 5, 3)).toBe(3); }); it('returns `null` or `undefined` if they are values in the map', () => { - expect(mapGetWithDefault(new Map([[1, null]]), 1, 3)).toBeNull(); - expect(mapGetWithDefault(new Map([[1, undefined]]), 1, 3)).toBeUndefined(); + expect((0, (_collection || _load_collection()).mapGetWithDefault)(new Map([[1, null]]), 1, 3)).toBeNull(); + expect((0, (_collection || _load_collection()).mapGetWithDefault)(new Map([[1, undefined]]), 1, 3)).toBeUndefined(); }); }); describe('count', () => { it('returns how many values are in an iterable', () => { - expect(count([1, 2])).toBe(2); + expect((0, (_collection || _load_collection()).count)([1, 2])).toBe(2); }); }); describe('insideOut', () => { it('traverses correctly', () => { - expect([...insideOut([])]).toEqual([]); - expect([...insideOut(['a'])]).toEqual([['a', 0]]); - expect([...insideOut(['a', 'b'])]).toEqual([['b', 1], ['a', 0]]); - expect([...insideOut(['a', 'b', 'c'])]).toEqual([ - ['b', 1], - ['a', 0], - ['c', 2], - ]); - expect([...insideOut(['a', 'b', 'c', 'd'])]).toEqual([ - ['c', 2], - ['b', 1], - ['d', 3], - ['a', 0], - ]); + expect([...(0, (_collection || _load_collection()).insideOut)([])]).toEqual([]); + expect([...(0, (_collection || _load_collection()).insideOut)(['a'])]).toEqual([['a', 0]]); + expect([...(0, (_collection || _load_collection()).insideOut)(['a', 'b'])]).toEqual([['b', 1], ['a', 0]]); + expect([...(0, (_collection || _load_collection()).insideOut)(['a', 'b', 'c'])]).toEqual([ + ['b', 1], + ['a', 0], + ['c', 2]]); + + expect([...(0, (_collection || _load_collection()).insideOut)(['a', 'b', 'c', 'd'])]).toEqual([ + ['c', 2], + ['b', 1], + ['d', 3], + ['a', 0]]); + }); it('traverses correctly with an index', () => { - expect([...insideOut([], 99)]).toEqual([]); - expect([...insideOut(['a'], 99)]).toEqual([['a', 0]]); - expect([...insideOut(['a', 'b'], 99)]).toEqual([['b', 1], ['a', 0]]); - expect([...insideOut(['a', 'b', 'c'], 99)]).toEqual([ - ['c', 2], - ['b', 1], - ['a', 0], - ]); - - expect([...insideOut([], -99)]).toEqual([]); - expect([...insideOut(['a'], -99)]).toEqual([['a', 0]]); - expect([...insideOut(['a', 'b'], -99)]).toEqual([['a', 0], ['b', 1]]); - expect([...insideOut(['a', 'b', 'c'], -99)]).toEqual([ - ['a', 0], - ['b', 1], - ['c', 2], - ]); - - expect([...insideOut(['a', 'b'], 1)]).toEqual([['b', 1], ['a', 0]]); - expect([...insideOut(['a', 'b'], 0)]).toEqual([['a', 0], ['b', 1]]); - - expect([...insideOut(['a', 'b', 'c'], 1)]).toEqual([ - ['b', 1], - ['a', 0], - ['c', 2], - ]); - expect([...insideOut(['a', 'b', 'c', 'd'], 1)]).toEqual([ - ['b', 1], - ['a', 0], - ['c', 2], - ['d', 3], - ]); - expect([...insideOut(['a', 'b', 'c', 'd'], 2)]).toEqual([ - ['c', 2], - ['b', 1], - ['d', 3], - ['a', 0], - ]); + expect([...(0, (_collection || _load_collection()).insideOut)([], 99)]).toEqual([]); + expect([...(0, (_collection || _load_collection()).insideOut)(['a'], 99)]).toEqual([['a', 0]]); + expect([...(0, (_collection || _load_collection()).insideOut)(['a', 'b'], 99)]).toEqual([['b', 1], ['a', 0]]); + expect([...(0, (_collection || _load_collection()).insideOut)(['a', 'b', 'c'], 99)]).toEqual([ + ['c', 2], + ['b', 1], + ['a', 0]]); + + + expect([...(0, (_collection || _load_collection()).insideOut)([], -99)]).toEqual([]); + expect([...(0, (_collection || _load_collection()).insideOut)(['a'], -99)]).toEqual([['a', 0]]); + expect([...(0, (_collection || _load_collection()).insideOut)(['a', 'b'], -99)]).toEqual([['a', 0], ['b', 1]]); + expect([...(0, (_collection || _load_collection()).insideOut)(['a', 'b', 'c'], -99)]).toEqual([ + ['a', 0], + ['b', 1], + ['c', 2]]); + + + expect([...(0, (_collection || _load_collection()).insideOut)(['a', 'b'], 1)]).toEqual([['b', 1], ['a', 0]]); + expect([...(0, (_collection || _load_collection()).insideOut)(['a', 'b'], 0)]).toEqual([['a', 0], ['b', 1]]); + + expect([...(0, (_collection || _load_collection()).insideOut)(['a', 'b', 'c'], 1)]).toEqual([ + ['b', 1], + ['a', 0], + ['c', 2]]); + + expect([...(0, (_collection || _load_collection()).insideOut)(['a', 'b', 'c', 'd'], 1)]).toEqual([ + ['b', 1], + ['a', 0], + ['c', 2], + ['d', 3]]); + + expect([...(0, (_collection || _load_collection()).insideOut)(['a', 'b', 'c', 'd'], 2)]).toEqual([ + ['c', 2], + ['b', 1], + ['d', 3], + ['a', 0]]); + }); }); describe('range', () => { it('includes the start value, but not the stop value', () => { - expect([...range(1, 4)]).toEqual([1, 2, 3]); + expect([...(0, (_collection || _load_collection()).range)(1, 4)]).toEqual([1, 2, 3]); }); it('is empty if stop is less than, or equal to, start', () => { - expect([...range(2, 1)]).toEqual([]); - expect([...range(1, 1)]).toEqual([]); + expect([...(0, (_collection || _load_collection()).range)(2, 1)]).toEqual([]); + expect([...(0, (_collection || _load_collection()).range)(1, 1)]).toEqual([]); }); }); @@ -701,37 +701,37 @@ describe('objectFromPairs', () => { yield ['a', 1]; yield ['b', 2]; } - expect(objectFromPairs(gen())).toEqual({a: 1, b: 2}); + expect((0, (_collection || _load_collection()).objectFromPairs)(gen())).toEqual({ a: 1, b: 2 }); }); }); describe('objectMapValues', () => { it('maps values', () => { - const mapped = objectMapValues({a: 1, b: 2}, v => v + 1); - expect(mapped).toEqual({a: 2, b: 3}); + const mapped = (0, (_collection || _load_collection()).objectMapValues)({ a: 1, b: 2 }, v => v + 1); + expect(mapped).toEqual({ a: 2, b: 3 }); }); it('can project keys too', () => { - const mapped = objectMapValues({a: 1, b: 2}, (v, k) => k); - expect(mapped).toEqual({a: 'a', b: 'b'}); + const mapped = (0, (_collection || _load_collection()).objectMapValues)({ a: 1, b: 2 }, (v, k) => k); + expect(mapped).toEqual({ a: 'a', b: 'b' }); }); }); describe('mapFromObject', () => { it('converts a object to an map', () => { expect( - mapEqual(mapFromObject({a: 1, b: 2}), new Map([['a', 1], ['b', 2]])), - ).toEqual(true); + (0, (_collection || _load_collection()).mapEqual)((0, (_collection || _load_collection()).mapFromObject)({ a: 1, b: 2 }), new Map([['a', 1], ['b', 2]]))). + toEqual(true); }); }); describe('distinct', () => { it('returns the unique values mapped (or keys)', () => { - expect(distinct([1, 2, 3])).toEqual([1, 2, 3]); - expect(distinct(['1', '2', '3'])).toEqual(['1', '2', '3']); - expect(distinct([1, 2, 3, 4], x => String(x % 2 === 0))).toEqual([1, 2]); + expect((0, (_collection || _load_collection()).distinct)([1, 2, 3])).toEqual([1, 2, 3]); + expect((0, (_collection || _load_collection()).distinct)(['1', '2', '3'])).toEqual(['1', '2', '3']); + expect((0, (_collection || _load_collection()).distinct)([1, 2, 3, 4], x => String(x % 2 === 0))).toEqual([1, 2]); expect( - distinct([{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 4}], o => String(o.x)), - ).toEqual([{x: 1}, {x: 2}, {x: 3}, {x: 4}]); + (0, (_collection || _load_collection()).distinct)([{ x: 1 }, { x: 2 }, { x: 3 }, { x: 4 }, { x: 4 }], o => String(o.x))). + toEqual([{ x: 1 }, { x: 2 }, { x: 3 }, { x: 4 }]); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/spec/debounce-spec.js b/modules/nuclide-commons/spec/debounce-spec.js index 76328e1f..4458d7e1 100644 --- a/modules/nuclide-commons/spec/debounce-spec.js +++ b/modules/nuclide-commons/spec/debounce-spec.js @@ -1,33 +1,33 @@ -/** - * 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 - * @format - */ - -import invariant from 'assert'; -import debounce from '../debounce'; - -describe('debounce()', () => { - it('only calls function once after time advances', () => { - const timerCallback: any = jasmine.createSpy('timerCallback'); - const debouncedFunc = debounce(timerCallback, 100, false); +'use strict';var _debounce; - debouncedFunc(); - expect(timerCallback).not.toHaveBeenCalled(); - advanceClock(101); + + + + + + + + + + +function _load_debounce() {return _debounce = _interopRequireDefault(require('../debounce'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */describe('debounce()', () => {it('only calls function once after time advances', () => {const timerCallback = jasmine.createSpy('timerCallback');const debouncedFunc = (0, (_debounce || _load_debounce()).default)(timerCallback, 100, false);debouncedFunc();expect(timerCallback).not.toHaveBeenCalled();advanceClock(101); expect(timerCallback).toHaveBeenCalled(); }); it('disposes', () => { - const timerCallback: any = jasmine.createSpy('timerCallback'); - const debouncedFunc = debounce(timerCallback, 100, false); + const timerCallback = jasmine.createSpy('timerCallback'); + const debouncedFunc = (0, (_debounce || _load_debounce()).default)(timerCallback, 100, false); debouncedFunc(); expect(timerCallback).not.toHaveBeenCalled(); @@ -39,8 +39,8 @@ describe('debounce()', () => { }); it('does not swallow flow types', () => { - const func = (a: string): number => 1; - const debounced = debounce(func, 0); + const func = a => 1; + const debounced = (0, (_debounce || _load_debounce()).default)(func, 0); const ret = debounced('bar'); // $FlowIgnore: func's first param should be a string. @@ -48,10 +48,10 @@ describe('debounce()', () => { expect(() => { // $FlowIgnore: debounce's return type is "maybe func's return" type. - (ret: number); + ret; // This is false because we haven't waited for the timer. - invariant(ret != null); - (ret: number); + if (!(ret != null)) {throw new Error('Invariant violation: "ret != null"');} + ret; }).toThrow(); debounced.dispose(); @@ -61,4 +61,4 @@ describe('debounce()', () => { debounced.bar(); }).toThrow(); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/spec/event-spec.js b/modules/nuclide-commons/spec/event-spec.js index d8d3ac12..86b95e0a 100644 --- a/modules/nuclide-commons/spec/event-spec.js +++ b/modules/nuclide-commons/spec/event-spec.js @@ -1,28 +1,28 @@ -/** - * 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 - * @format - */ - -import invariant from 'assert'; -import EventEmitter from 'events'; -import {attachEvent, observableFromSubscribeFunction} from '../event'; - -describe('attachEvent', () => { - describe('the returned disposable', () => { - it("doesn't remove other listeners when disposed multiple times", () => { - const foo = jasmine.createSpy('foo'); - const emitter = new EventEmitter(); - const d1 = attachEvent(emitter, 'event', foo); - attachEvent(emitter, 'event', foo); - d1.dispose(); - d1.dispose(); +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + + + + + + + + + + + + +var _events = _interopRequireDefault(require('events'));var _event; +function _load_event() {return _event = require('../event');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */describe('attachEvent', () => {describe('the returned disposable', () => {it("doesn't remove other listeners when disposed multiple times", () => {const foo = jasmine.createSpy('foo');const emitter = new _events.default();const d1 = (0, (_event || _load_event()).attachEvent)(emitter, 'event', foo);(0, (_event || _load_event()).attachEvent)(emitter, 'event', foo);d1.dispose();d1.dispose(); emitter.emit('event'); expect(foo).toHaveBeenCalled(); }); @@ -30,8 +30,8 @@ describe('attachEvent', () => { }); describe('observableFromSubscribeFunction', () => { - let callback: ?(item: number) => mixed; - let disposable: ?IDisposable; + let callback; + let disposable; // The subscribe function will put the given callback and the returned disposable in the variables // above for inspection. @@ -40,8 +40,8 @@ describe('observableFromSubscribeFunction', () => { disposable = { dispose() { callback = null; - }, - }; + } }; + spyOn(disposable, 'dispose').andCallThrough(); return disposable; }; @@ -52,31 +52,31 @@ describe('observableFromSubscribeFunction', () => { }); it('should not call the subscription function until the Observable is subscribed to', () => { - const observable = observableFromSubscribeFunction(subscribeFunction); + const observable = (0, (_event || _load_event()).observableFromSubscribeFunction)(subscribeFunction); expect(callback).toBeNull(); observable.subscribe(() => {}); expect(callback).not.toBeNull(); }); it('should send events to the observable stream', () => { - waitsForPromise(async () => { - const result = observableFromSubscribeFunction(subscribeFunction) - .take(2) - .toArray() - .toPromise(); - invariant(callback != null); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const result = (0, (_event || _load_event()).observableFromSubscribeFunction)(subscribeFunction). + take(2). + toArray(). + toPromise();if (!( + callback != null)) {throw new Error('Invariant violation: "callback != null"');} callback(1); callback(2); - expect(await result).toEqual([1, 2]); - }); + expect((yield result)).toEqual([1, 2]); + })); }); it('should properly unsubscribe and resubscribe', () => { - const observable = observableFromSubscribeFunction(subscribeFunction); + const observable = (0, (_event || _load_event()).observableFromSubscribeFunction)(subscribeFunction); let subscription = observable.subscribe(() => {}); - expect(callback).not.toBeNull(); + expect(callback).not.toBeNull();if (!( - invariant(disposable != null); + disposable != null)) {throw new Error('Invariant violation: "disposable != null"');} expect(disposable.dispose).not.toHaveBeenCalled(); subscription.unsubscribe(); expect(disposable.dispose).toHaveBeenCalled(); @@ -91,4 +91,4 @@ describe('observableFromSubscribeFunction', () => { subscription.unsubscribe(); expect(disposable.dispose).toHaveBeenCalled(); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/spec/fixtures/symbol-definition-preview-sample.js b/modules/nuclide-commons/spec/fixtures/symbol-definition-preview-sample.js index 6536861e..daebf0ed 100644 --- a/modules/nuclide-commons/spec/fixtures/symbol-definition-preview-sample.js +++ b/modules/nuclide-commons/spec/fixtures/symbol-definition-preview-sample.js @@ -1,51 +1,52 @@ -/** - * 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. - * - * @flow - */ -// license header above without @format -// eslint-disable-next-line -const A_CONSTANT = 42; -const SOME_OTHER_CONSTANT = 24; +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + + + + + + + + + + + + + +aSingleLineFunctionSignature = aSingleLineFunctionSignature;exports. + + + +aMultiLineFunctionSignature = aMultiLineFunctionSignature;exports. + + + + +aPoorlyIndentedFunction = aPoorlyIndentedFunction; /** + * 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. + * + * + */ // license header above without @format // eslint-disable-next-line +const A_CONSTANT = 42;const SOME_OTHER_CONSTANT = 24; // eslint-disable-next-line const A_MULTILINE_CONST = ` hey look I span multiple lines -`; - -type Something = { - name: string, - age?: number, -}; - -export function aSingleLineFunctionSignature() { - return A_CONSTANT + SOME_OTHER_CONSTANT; -} - -export function aMultiLineFunctionSignature( - aReallyReallyLongArgumentNameThatWouldRequireThisToBreakAcrossMultipleLines: Something, -): number { - return 97; -} - - export function aPoorlyIndentedFunction( -aReallyReallyLongArgumentNameThatWouldRequireThisToBreakAcrossMultipleLines: Something, -): number { - return 97; -} - -type SomethingComplex = { - properties: { - name: string, - age?: number, - }, -}; - -const foo: ?SomethingComplex = null; -foo; +`;function aSingleLineFunctionSignature() {return A_CONSTANT + SOME_OTHER_CONSTANT;}function aMultiLineFunctionSignature(aReallyReallyLongArgumentNameThatWouldRequireThisToBreakAcrossMultipleLines) {return 97;}function aPoorlyIndentedFunction(aReallyReallyLongArgumentNameThatWouldRequireThisToBreakAcrossMultipleLines) {return 97;}const foo = null;foo; \ No newline at end of file diff --git a/modules/nuclide-commons/spec/fixtures/throw.js b/modules/nuclide-commons/spec/fixtures/throw.js index 54c55e8c..ab5a6e0b 100644 --- a/modules/nuclide-commons/spec/fixtures/throw.js +++ b/modules/nuclide-commons/spec/fixtures/throw.js @@ -1,13 +1,13 @@ -/** - * 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 - * @format - */ +'use strict'; /** + * 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. + * + * + * @format + */ -throw new Error('Errored!'); +throw new Error('Errored!'); \ No newline at end of file diff --git a/modules/nuclide-commons/spec/fixtures/toBeMocked.js b/modules/nuclide-commons/spec/fixtures/toBeMocked.js index 009f7899..c5559f91 100644 --- a/modules/nuclide-commons/spec/fixtures/toBeMocked.js +++ b/modules/nuclide-commons/spec/fixtures/toBeMocked.js @@ -1,15 +1,23 @@ -/** - * 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 - * @format - */ - -export function importedFunction(arg: any): any { - return 0; -} +"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + +importedFunction = importedFunction; /** + * 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. + * + * + * @format + */function importedFunction(arg) {return 0;} \ No newline at end of file diff --git a/modules/nuclide-commons/spec/fixtures/toBeTested.js b/modules/nuclide-commons/spec/fixtures/toBeTested.js index 8eda9295..30153592 100644 --- a/modules/nuclide-commons/spec/fixtures/toBeTested.js +++ b/modules/nuclide-commons/spec/fixtures/toBeTested.js @@ -1,17 +1,27 @@ -/** - * 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 - * @format - */ - -import {importedFunction} from './toBeMocked'; - -export function functionToTest(): any { - return importedFunction(42); -} +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + +functionToTest = functionToTest;var _toBeMocked;function _load_toBeMocked() {return _toBeMocked = require('./toBeMocked');}function functionToTest() { + return (0, (_toBeMocked || _load_toBeMocked()).importedFunction)(42); +} /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/spec/fsPromise-spec.js b/modules/nuclide-commons/spec/fsPromise-spec.js index ac55ea42..ead200fc 100644 --- a/modules/nuclide-commons/spec/fsPromise-spec.js +++ b/modules/nuclide-commons/spec/fsPromise-spec.js @@ -1,212 +1,212 @@ -/** - * 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 - * @format - */ - -import invariant from 'assert'; -import fs from 'fs'; -import temp from 'temp'; -import nuclideUri from '../nuclideUri'; -import fsPromise from '../fsPromise'; -import {generateFixture} from '../test-helpers'; - -temp.track(); - -describe('fsPromise test suite', () => { - describe('findNearestFile()', () => { - let dirPath: string = (null: any); +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); - beforeEach(() => { - waitsForPromise(async () => { - dirPath = await generateFixture( - 'nearest_test', - new Map([ - ['.some_file', 'just some file'], - ['nested_dir/.another_file', 'just another file'], - ]), - ); - }); + + + + + + + + + + + +var _fs = _interopRequireDefault(require('fs'));var _temp; +function _load_temp() {return _temp = _interopRequireDefault(require('temp'));}var _nuclideUri; +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('../nuclideUri'));}var _fsPromise; +function _load_fsPromise() {return _fsPromise = _interopRequireDefault(require('../fsPromise'));}var _testHelpers; +function _load_testHelpers() {return _testHelpers = require('../test-helpers');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +(_temp || _load_temp()).default.track(); /** + * 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. + * + * + * @format + */describe('fsPromise test suite', () => {describe('findNearestFile()', () => {let dirPath = null;beforeEach(() => {waitsForPromise((0, _asyncToGenerator.default)(function* () {dirPath = yield (0, (_testHelpers || _load_testHelpers()).generateFixture)('nearest_test', new Map([ + ['.some_file', 'just some file'], + ['nested_dir/.another_file', 'just another file']])); + + + })); }); it('find the file if given the exact directory', () => { - waitsForPromise(async () => { - const foundPath = await fsPromise.findNearestFile( - '.some_file', - dirPath, - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const foundPath = yield (_fsPromise || _load_fsPromise()).default.findNearestFile( + '.some_file', + dirPath); + expect(foundPath).toBe(dirPath); - }); + })); }); it('find the file if given a nested directory', () => { - waitsForPromise(async () => { - const foundPath = await fsPromise.findNearestFile( - '.some_file', - nuclideUri.join(dirPath, 'nested_dir'), - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const foundPath = yield (_fsPromise || _load_fsPromise()).default.findNearestFile( + '.some_file', + (_nuclideUri || _load_nuclideUri()).default.join(dirPath, 'nested_dir')); + expect(foundPath).toBe(dirPath); - }); + })); }); it('does not find the file if not existing', () => { - waitsForPromise(async () => { - const foundPath = await fsPromise.findNearestFile( - 'non-existent.txt', - nuclideUri.join(dirPath, 'nested_dir'), - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const foundPath = yield (_fsPromise || _load_fsPromise()).default.findNearestFile( + 'non-existent.txt', + (_nuclideUri || _load_nuclideUri()).default.join(dirPath, 'nested_dir')); + expect(foundPath).toBe(null); - }); + })); }); }); describe('findFurthestFile()', () => { - let dirPath: string = (null: any); + let dirPath = null; beforeEach(() => { - waitsForPromise(async () => { - dirPath = await generateFixture( - 'furthest_test', - new Map([ - ['0/.some_file', 'just a file'], - ['0/1/.some_file', 'just b file'], - // Skip one file to test consecutive vs non-consecutive. - // ['0/1/2', 'just c file'], - ['0/1/2/3/.some_file', 'just d file'], - ['0/1/2/3/4/.some_file', 'just f file'], - ]), - ); - }); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + dirPath = yield (0, (_testHelpers || _load_testHelpers()).generateFixture)( + 'furthest_test', + new Map([ + ['0/.some_file', 'just a file'], + ['0/1/.some_file', 'just b file'], + // Skip one file to test consecutive vs non-consecutive. + // ['0/1/2', 'just c file'], + ['0/1/2/3/.some_file', 'just d file'], + ['0/1/2/3/4/.some_file', 'just f file']])); + + + })); }); it('find the file if given the exact directory', () => { - waitsForPromise(async () => { - const expectedPath = nuclideUri.join(dirPath, '0'); - const foundPath = await fsPromise.findFurthestFile( - '.some_file', - expectedPath, - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const expectedPath = (_nuclideUri || _load_nuclideUri()).default.join(dirPath, '0'); + const foundPath = yield (_fsPromise || _load_fsPromise()).default.findFurthestFile( + '.some_file', + expectedPath); + expect(foundPath).toBe(expectedPath); - }); + })); }); it('finds the furthest file if given a nested directory', () => { - waitsForPromise(async () => { - const expectedPath = nuclideUri.join(dirPath, '0'); - const startPath = nuclideUri.join(dirPath, '0/1/2/3/4'); - const foundPath = await fsPromise.findFurthestFile( - '.some_file', - startPath, - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const expectedPath = (_nuclideUri || _load_nuclideUri()).default.join(dirPath, '0'); + const startPath = (_nuclideUri || _load_nuclideUri()).default.join(dirPath, '0/1/2/3/4'); + const foundPath = yield (_fsPromise || _load_fsPromise()).default.findFurthestFile( + '.some_file', + startPath); + expect(foundPath).toBe(expectedPath); - }); + })); }); it('terminates search as soon as file is not found if given the stopOnMissing flag', () => { - waitsForPromise(async () => { - const expectedPath = nuclideUri.join(dirPath, '0/1/2/3'); - const startPath = nuclideUri.join(dirPath, '0/1/2/3/4'); - const foundPath = await fsPromise.findFurthestFile( - '.some_file', - startPath, - true /* stopOnMissing */, - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const expectedPath = (_nuclideUri || _load_nuclideUri()).default.join(dirPath, '0/1/2/3'); + const startPath = (_nuclideUri || _load_nuclideUri()).default.join(dirPath, '0/1/2/3/4'); + const foundPath = yield (_fsPromise || _load_fsPromise()).default.findFurthestFile( + '.some_file', + startPath, + true /* stopOnMissing */); + expect(foundPath).toBe(expectedPath); - }); + })); }); it('does not find the file if not existing', () => { - waitsForPromise(async () => { - const startPath = nuclideUri.join(dirPath, '0/1/2/3/4'); - const foundPath = await fsPromise.findFurthestFile( - 'non-existent.txt', - startPath, - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const startPath = (_nuclideUri || _load_nuclideUri()).default.join(dirPath, '0/1/2/3/4'); + const foundPath = yield (_fsPromise || _load_fsPromise()).default.findFurthestFile( + 'non-existent.txt', + startPath); + expect(foundPath).toBe(null); - }); + })); }); }); describe('getCommonAncestorDirectory', () => { it('gets the parent directory', () => { expect( - fsPromise.getCommonAncestorDirectory([ - '/foo/bar.txt', - '/foo/baz/lol.txt', - ]), - ).toBe('/foo'); + (_fsPromise || _load_fsPromise()).default.getCommonAncestorDirectory([ + '/foo/bar.txt', + '/foo/baz/lol.txt'])). + + toBe('/foo'); expect( - fsPromise.getCommonAncestorDirectory([ - '/foo/bar/abc/def/abc.txt', - '/foo/bar/lol.txt', - ]), - ).toBe('/foo/bar'); + (_fsPromise || _load_fsPromise()).default.getCommonAncestorDirectory([ + '/foo/bar/abc/def/abc.txt', + '/foo/bar/lol.txt'])). + + toBe('/foo/bar'); }); }); describe('writeFileAtomic', () => { - let pathToWriteFile: string; + let pathToWriteFile; beforeEach(() => { - const tempDir = temp.mkdirSync(); - pathToWriteFile = nuclideUri.join(tempDir, 'test'); + const tempDir = (_temp || _load_temp()).default.mkdirSync(); + pathToWriteFile = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, 'test'); }); it('can write to a file', () => { - waitsForPromise(async () => { - await fsPromise.writeFileAtomic( - pathToWriteFile, - "I'm a little teapot.\n", - ); - expect(fs.readFileSync(pathToWriteFile).toString()).toEqual( - "I'm a little teapot.\n", - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + yield (_fsPromise || _load_fsPromise()).default.writeFileAtomic( + pathToWriteFile, + "I'm a little teapot.\n"); + + expect(_fs.default.readFileSync(pathToWriteFile).toString()).toEqual( + "I'm a little teapot.\n"); + // eslint-disable-next-line no-bitwise - expect(fs.statSync(pathToWriteFile).mode & 0o777).toEqual( - 0o666 & ~process.umask(), // eslint-disable-line no-bitwise + expect(_fs.default.statSync(pathToWriteFile).mode & 0o777).toEqual( + 0o666 & ~process.umask() // eslint-disable-line no-bitwise ); - }); + })); }); it('calls mkdirp', () => { - waitsForPromise(async () => { - const subPath = nuclideUri.join(pathToWriteFile, 'test'); - await fsPromise.writeFileAtomic(subPath, 'test1234\n'); - expect(fs.readFileSync(subPath).toString()).toEqual('test1234\n'); - }); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const subPath = (_nuclideUri || _load_nuclideUri()).default.join(pathToWriteFile, 'test'); + yield (_fsPromise || _load_fsPromise()).default.writeFileAtomic(subPath, 'test1234\n'); + expect(_fs.default.readFileSync(subPath).toString()).toEqual('test1234\n'); + })); }); it('preserves permissions on files', () => { - fs.writeFileSync(pathToWriteFile, 'test'); - fs.chmodSync(pathToWriteFile, 0o700); + _fs.default.writeFileSync(pathToWriteFile, 'test'); + _fs.default.chmodSync(pathToWriteFile, 0o700); - waitsForPromise(async () => { - await fsPromise.writeFileAtomic(pathToWriteFile, 'test2'); - expect(fs.readFileSync(pathToWriteFile).toString()).toEqual('test2'); - const stat = fs.statSync(pathToWriteFile); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + yield (_fsPromise || _load_fsPromise()).default.writeFileAtomic(pathToWriteFile, 'test2'); + expect(_fs.default.readFileSync(pathToWriteFile).toString()).toEqual('test2'); + const stat = _fs.default.statSync(pathToWriteFile); // eslint-disable-next-line no-bitwise expect(stat.mode & 0o777).toEqual(0o700); - }); + })); }); it('errors if file cannot be written', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { let err; try { - await fsPromise.writeFileAtomic( - pathToWriteFile + '/that/is/missing/', - 'something', - ); + yield (_fsPromise || _load_fsPromise()).default.writeFileAtomic( + pathToWriteFile + '/that/is/missing/', + 'something'); + } catch (e) { err = e; - } - invariant(err != null, 'Expected an error'); - }); + }if (!( + err != null)) {throw new Error('Expected an error');} + })); }); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/spec/humanizeKeystroke-spec.js b/modules/nuclide-commons/spec/humanizeKeystroke-spec.js index d9baa7e1..ba4f14e9 100644 --- a/modules/nuclide-commons/spec/humanizeKeystroke-spec.js +++ b/modules/nuclide-commons/spec/humanizeKeystroke-spec.js @@ -1,96 +1,106 @@ -/** - * 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 - * @format - */ - -import humanizeKeystroke from '../humanizeKeystroke'; +'use strict';var _humanizeKeystroke; + + + + + + + + + + + +function _load_humanizeKeystroke() {return _humanizeKeystroke = _interopRequireDefault(require('../humanizeKeystroke'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} describe('nuclide-keystroke-label', () => { // adapted from https://github.com/atom/underscore-plus/blob/master/spec/underscore-plus-spec.coffee describe('humanizeKeystroke', () => { it('replaces single keystroke', () => { - expect(humanizeKeystroke('cmd-O', 'darwin')).toEqual('⌘⇧O'); - expect(humanizeKeystroke('cmd-O', 'linux')).toEqual('Cmd+Shift+O'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-O', 'darwin')).toEqual('⌘⇧O'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-O', 'linux')).toEqual('Cmd+Shift+O'); + + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-shift-up', 'darwin')).toEqual('⌘⇧↑'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-shift-up', 'linux')).toEqual( + 'Cmd+Shift+Up'); + + + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-option-down', 'darwin')).toEqual('⌘⌥↓'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-option-down', 'linux')).toEqual( + 'Cmd+Alt+Down'); + - expect(humanizeKeystroke('cmd-shift-up', 'darwin')).toEqual('⌘⇧↑'); - expect(humanizeKeystroke('cmd-shift-up', 'linux')).toEqual( - 'Cmd+Shift+Up', - ); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-option-left', 'darwin')).toEqual('⌘⌥←'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-option-left', 'linux')).toEqual( + 'Cmd+Alt+Left'); - expect(humanizeKeystroke('cmd-option-down', 'darwin')).toEqual('⌘⌥↓'); - expect(humanizeKeystroke('cmd-option-down', 'linux')).toEqual( - 'Cmd+Alt+Down', - ); - expect(humanizeKeystroke('cmd-option-left', 'darwin')).toEqual('⌘⌥←'); - expect(humanizeKeystroke('cmd-option-left', 'linux')).toEqual( - 'Cmd+Alt+Left', - ); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-option-right', 'darwin')).toEqual('⌘⌥→'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-option-right', 'linux')).toEqual( + 'Cmd+Alt+Right'); - expect(humanizeKeystroke('cmd-option-right', 'darwin')).toEqual('⌘⌥→'); - expect(humanizeKeystroke('cmd-option-right', 'linux')).toEqual( - 'Cmd+Alt+Right', - ); - expect(humanizeKeystroke('cmd-o', 'darwin')).toEqual('⌘O'); - expect(humanizeKeystroke('cmd-o', 'linux')).toEqual('Cmd+O'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-o', 'darwin')).toEqual('⌘O'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-o', 'linux')).toEqual('Cmd+O'); - expect(humanizeKeystroke('ctrl-2', 'darwin')).toEqual('⌃2'); - expect(humanizeKeystroke('ctrl-2', 'linux')).toEqual('Ctrl+2'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('ctrl-2', 'darwin')).toEqual('⌃2'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('ctrl-2', 'linux')).toEqual('Ctrl+2'); - expect(humanizeKeystroke('cmd-space', 'darwin')).toEqual('⌘space'); - expect(humanizeKeystroke('cmd-space', 'linux')).toEqual('Cmd+Space'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-space', 'darwin')).toEqual('⌘space'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-space', 'linux')).toEqual('Cmd+Space'); - expect(humanizeKeystroke('cmd-|', 'darwin')).toEqual('⌘⇧\\'); - expect(humanizeKeystroke('cmd-|', 'linux')).toEqual('Cmd+Shift+\\'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-|', 'darwin')).toEqual('⌘⇧\\'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-|', 'linux')).toEqual('Cmd+Shift+\\'); - expect(humanizeKeystroke('cmd-}', 'darwin')).toEqual('⌘⇧]'); - expect(humanizeKeystroke('cmd-}', 'linux')).toEqual('Cmd+Shift+]'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-}', 'darwin')).toEqual('⌘⇧]'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-}', 'linux')).toEqual('Cmd+Shift+]'); - expect(humanizeKeystroke('cmd--', 'darwin')).toEqual('⌘-'); - expect(humanizeKeystroke('cmd--', 'linux')).toEqual('Cmd+-'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd--', 'darwin')).toEqual('⌘-'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd--', 'linux')).toEqual('Cmd+-'); }); it('correctly replaces keystrokes with shift and capital letter', () => { - expect(humanizeKeystroke('cmd-shift-P', 'darwin')).toEqual('⌘⇧P'); - expect(humanizeKeystroke('cmd-shift-P', 'linux')).toEqual('Cmd+Shift+P'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-shift-P', 'darwin')).toEqual('⌘⇧P'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-shift-P', 'linux')).toEqual('Cmd+Shift+P'); }); it('replaces multiple keystrokes', () => { - expect(humanizeKeystroke('cmd-O cmd-n', 'darwin')).toEqual('⌘⇧O ⌘N'); - expect(humanizeKeystroke('cmd-O cmd-n', 'linux')).toEqual( - 'Cmd+Shift+O Cmd+N', - ); - - expect(humanizeKeystroke('cmd-shift-- cmd-n', 'darwin')).toEqual( - '⌘⇧- ⌘N', - ); - expect(humanizeKeystroke('cmd-shift-- cmd-n', 'linux')).toEqual( - 'Cmd+Shift+- Cmd+N', - ); - - expect(humanizeKeystroke('cmd-k right', 'darwin')).toEqual('⌘K →'); - expect(humanizeKeystroke('cmd-k right', 'linux')).toEqual('Cmd+K Right'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-O cmd-n', 'darwin')).toEqual('⌘⇧O ⌘N'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-O cmd-n', 'linux')).toEqual( + 'Cmd+Shift+O Cmd+N'); + + + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-shift-- cmd-n', 'darwin')).toEqual( + '⌘⇧- ⌘N'); + + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-shift-- cmd-n', 'linux')).toEqual( + 'Cmd+Shift+- Cmd+N'); + + + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-k right', 'darwin')).toEqual('⌘K →'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-k right', 'linux')).toEqual('Cmd+K Right'); }); it('formats function keys', () => { - expect(humanizeKeystroke('cmd-f2', 'darwin')).toEqual('⌘F2'); - expect(humanizeKeystroke('cmd-f2', 'linux')).toEqual('Cmd+F2'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-f2', 'darwin')).toEqual('⌘F2'); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('cmd-f2', 'linux')).toEqual('Cmd+F2'); }); it('handles junk input', () => { // $FlowFixMe: Deliberately testing invalid input. - expect(humanizeKeystroke()).toEqual(undefined); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)()).toEqual(undefined); // $FlowFixMe: Deliberately testing invalid input. - expect(humanizeKeystroke(null)).toEqual(null); - expect(humanizeKeystroke('')).toEqual(''); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)(null)).toEqual(null); + expect((0, (_humanizeKeystroke || _load_humanizeKeystroke()).default)('')).toEqual(''); }); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/spec/matchIndexesToRanges-spec.js b/modules/nuclide-commons/spec/matchIndexesToRanges-spec.js index fc991d27..505bb639 100644 --- a/modules/nuclide-commons/spec/matchIndexesToRanges-spec.js +++ b/modules/nuclide-commons/spec/matchIndexesToRanges-spec.js @@ -1,31 +1,41 @@ -/** - * 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 - * @format - */ - -import matchIndexesToRanges from '../matchIndexesToRanges'; +'use strict';var _matchIndexesToRanges; + + + + + + + + + + + +function _load_matchIndexesToRanges() {return _matchIndexesToRanges = _interopRequireDefault(require('../matchIndexesToRanges'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} describe('matchIndexesToRanges', () => { it('makes single character ranges for nonconsecutive values at consecutive indexes', () => { - expect(matchIndexesToRanges([1, 3, 5, 7, 9])).toEqual([ - [1, 2], - [3, 4], - [5, 6], - [7, 8], - [9, 10], - ]); + expect((0, (_matchIndexesToRanges || _load_matchIndexesToRanges()).default)([1, 3, 5, 7, 9])).toEqual([ + [1, 2], + [3, 4], + [5, 6], + [7, 8], + [9, 10]]); + }); it('collapses consecutive values into ranges', () => { expect( - matchIndexesToRanges([0, 1, 2, 3, 10, 11, 12, 20, 21, 22, 23, 24, 25]), - ).toEqual([[0, 4], [10, 13], [20, 26]]); + (0, (_matchIndexesToRanges || _load_matchIndexesToRanges()).default)([0, 1, 2, 3, 10, 11, 12, 20, 21, 22, 23, 24, 25])). + toEqual([[0, 4], [10, 13], [20, 26]]); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/spec/memoizeUntilChanged-spec.js b/modules/nuclide-commons/spec/memoizeUntilChanged-spec.js index 07d10ae9..2750cf6d 100644 --- a/modules/nuclide-commons/spec/memoizeUntilChanged-spec.js +++ b/modules/nuclide-commons/spec/memoizeUntilChanged-spec.js @@ -1,32 +1,32 @@ -/** - * 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 - * @format - */ - -import memoizeUntilChanged from '../memoizeUntilChanged'; - -const sum = (a, b) => a + b; - -describe('memoizeUntilChanged', () => { - it('memoizes', () => { - const spy = jasmine.createSpy().andCallFake(sum); - const f = memoizeUntilChanged(spy); - f(1, 2); - const result = f(1, 2); - expect(result).toBe(3); - expect(spy.callCount).toBe(1); - }); +'use strict';var _memoizeUntilChanged; + + + + + + + + + + + +function _load_memoizeUntilChanged() {return _memoizeUntilChanged = _interopRequireDefault(require('../memoizeUntilChanged'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +const sum = (a, b) => a + b; /** + * 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. + * + * + * @format + */describe('memoizeUntilChanged', () => {it('memoizes', () => {const spy = jasmine.createSpy().andCallFake(sum);const f = (0, (_memoizeUntilChanged || _load_memoizeUntilChanged()).default)(spy);f(1, 2);const result = f(1, 2);expect(result).toBe(3);expect(spy.callCount).toBe(1);}); it('resets when args change', () => { const spy = jasmine.createSpy().andCallFake(sum); - const f = memoizeUntilChanged(spy); + const f = (0, (_memoizeUntilChanged || _load_memoizeUntilChanged()).default)(spy); f(1, 2); const result = f(1, 3); expect(result).toBe(4); @@ -36,7 +36,7 @@ describe('memoizeUntilChanged', () => { it('preserves context', () => { let that; const obj = {}; - const f = memoizeUntilChanged(function f() { + const f = (0, (_memoizeUntilChanged || _load_memoizeUntilChanged()).default)(function f() { that = this; }); f.call(obj); @@ -45,7 +45,7 @@ describe('memoizeUntilChanged', () => { it('uses all args when memoizing by default', () => { const spy = jasmine.createSpy().andCallFake(sum); - const f = memoizeUntilChanged(spy); + const f = (0, (_memoizeUntilChanged || _load_memoizeUntilChanged()).default)(spy); f(1, 2); const result = f(1, 3); expect(result).toBe(4); @@ -54,14 +54,14 @@ describe('memoizeUntilChanged', () => { it('uses the key selector and comparator', () => { const spy = jasmine.createSpy().andCallFake(sum); - const f = memoizeUntilChanged( - spy, - // A pretty poor keyselector that uses the sum of the arguments as the key. Lots of collisions - // here! - (x, y) => x + y, - // Compare numbers. - (a, b) => a === b, - ); + const f = (0, (_memoizeUntilChanged || _load_memoizeUntilChanged()).default)( + spy, + // A pretty poor keyselector that uses the sum of the arguments as the key. Lots of collisions + // here! + (x, y) => x + y, + // Compare numbers. + (a, b) => a === b); + f(1, 2); f(2, 1); f(0, 3); @@ -69,4 +69,4 @@ describe('memoizeUntilChanged', () => { f(0, 4); expect(spy.callCount).toBe(2); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/spec/nice-spec.js b/modules/nuclide-commons/spec/nice-spec.js index 080b0a37..60f38026 100644 --- a/modules/nuclide-commons/spec/nice-spec.js +++ b/modules/nuclide-commons/spec/nice-spec.js @@ -1,112 +1,122 @@ -/** - * 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 - * @format - */ - -import typeof {niceSafeSpawn as niceSafeSpawnType} from '../nice'; - -import {uncachedRequire} from '../test-helpers'; -import {Observable} from 'rxjs'; +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _testHelpers; + + + + + + + + + + + + + +function _load_testHelpers() {return _testHelpers = require('../test-helpers');} +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} describe('nice', () => { - let niceSafeSpawn: niceSafeSpawnType = (null: any); + let niceSafeSpawn = null; - let whichSpy: JasmineSpy = (null: any); - let spawnSpy: JasmineSpy = (null: any); - let shouldFindNiceCommand: boolean = (null: any); - let shouldFindIoniceCommand: boolean = (null: any); + let whichSpy = null; + let spawnSpy = null; + let shouldFindNiceCommand = null; + let shouldFindIoniceCommand = null; // All we need here is a unique value to make sure that `nice` returns whatever `safeSpawn` // returns - const fakeSafeSpawnReturn: child_process$ChildProcess = ({}: any); + const fakeSafeSpawnReturn = {}; beforeEach(() => { shouldFindNiceCommand = true; shouldFindIoniceCommand = true; - whichSpy = spyOn(require('../which'), 'default').andCallFake( - async command => { + whichSpy = spyOn(require('../which'), 'default').andCallFake((() => {var _ref = (0, _asyncToGenerator.default)( + function* (command) { if ( - (shouldFindNiceCommand && command === 'nice') || - (shouldFindIoniceCommand && command === 'ionice') - ) { + shouldFindNiceCommand && command === 'nice' || + shouldFindIoniceCommand && command === 'ionice') + { return command; } else { return null; } - }, - ); + });return function (_x) {return _ref.apply(this, arguments);};})()); + spawnSpy = spyOn(require('../process'), 'spawn').andReturn( - Observable.of(fakeSafeSpawnReturn), - ); - ({niceSafeSpawn} = (uncachedRequire(require, '../nice'): any)); + _rxjsBundlesRxMinJs.Observable.of(fakeSafeSpawnReturn)); + + ({ niceSafeSpawn } = (0, (_testHelpers || _load_testHelpers()).uncachedRequire)(require, '../nice')); }); it('should spawn `nice` and return whatever spawn returns', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { const execOptions = {}; - const result = await niceSafeSpawn('echo', ['hi'], execOptions); + const result = yield niceSafeSpawn('echo', ['hi'], execOptions); expect(spawnSpy).toHaveBeenCalledWith( - 'ionice', - ['-n', '7', 'nice', 'echo', 'hi'], - execOptions, - ); + 'ionice', + ['-n', '7', 'nice', 'echo', 'hi'], + execOptions); + expect(result).toBe(fakeSafeSpawnReturn); - }); + })); }); it('should spawn the command normally if nice and ionice cannot be found', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { shouldFindNiceCommand = false; shouldFindIoniceCommand = false; const execOptions = {}; - const result = await niceSafeSpawn('echo', ['hi'], execOptions); + const result = yield niceSafeSpawn('echo', ['hi'], execOptions); expect(spawnSpy).toHaveBeenCalledWith('echo', ['hi'], execOptions); expect(result).toBe(fakeSafeSpawnReturn); - }); + })); }); it('should spawn with only nice if ionice cannot be found', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { shouldFindIoniceCommand = false; const execOptions = {}; - const result = await niceSafeSpawn('echo', ['hi'], execOptions); + const result = yield niceSafeSpawn('echo', ['hi'], execOptions); expect(spawnSpy).toHaveBeenCalledWith( - 'nice', - ['echo', 'hi'], - execOptions, - ); + 'nice', + ['echo', 'hi'], + execOptions); + expect(result).toBe(fakeSafeSpawnReturn); - }); + })); }); it('should spawn with only ionice if nice cannot be found', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { // I don't know when we would have ionice but not nice, but we may as well support this case. shouldFindNiceCommand = false; const execOptions = {}; - const result = await niceSafeSpawn('echo', ['hi'], execOptions); + const result = yield niceSafeSpawn('echo', ['hi'], execOptions); expect(spawnSpy).toHaveBeenCalledWith( - 'ionice', - ['-n', '7', 'echo', 'hi'], - execOptions, - ); + 'ionice', + ['-n', '7', 'echo', 'hi'], + execOptions); + expect(result).toBe(fakeSafeSpawnReturn); - }); + })); }); it('should call which only once per command and cache the result', () => { - waitsForPromise(async () => { - await niceSafeSpawn('echo', []); - await niceSafeSpawn('echo', []); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + yield niceSafeSpawn('echo', []); + yield niceSafeSpawn('echo', []); expect(whichSpy).toHaveBeenCalledWith('nice'); expect(whichSpy).toHaveBeenCalledWith('ionice'); expect(whichSpy.callCount).toBe(2); - }); + })); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/spec/nuclideUri-spec.js b/modules/nuclide-commons/spec/nuclideUri-spec.js index af87092c..774e751b 100644 --- a/modules/nuclide-commons/spec/nuclideUri-spec.js +++ b/modules/nuclide-commons/spec/nuclideUri-spec.js @@ -1,54 +1,54 @@ -/** - * 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 - * @format - */ - -import nuclideUri, {__TEST__} from '../nuclideUri'; -// eslint-disable-next-line rulesdir/prefer-nuclide-uri -import path from 'path'; - -describe('nuclide-uri', () => { - const localUri = '/usr/local/file'; - const badRemoteUriNoPath = 'nuclide://fb.com'; - const atomUri = 'atom://bla/bla'; - const remoteUri = nuclideUri.createRemoteUri('fb.com', '/usr/local'); - const remoteUriWithSpaces = nuclideUri.createRemoteUri('fb.com', '/a b/c d'); - const remoteUriWithHashes = nuclideUri.createRemoteUri( - 'fb.co.uk', - '/ab/#c.d #', - ); +'use strict';var _nuclideUri; + + + + + + + + + + + +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('../nuclideUri'));}var _nuclideUri2;function _load_nuclideUri2() {return _nuclideUri2 = require('../nuclideUri');} + +var _path = _interopRequireDefault(require('path'));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */describe('nuclide-uri', () => {const localUri = '/usr/local/file';const badRemoteUriNoPath = 'nuclide://fb.com';const atomUri = 'atom://bla/bla';const remoteUri = (_nuclideUri || _load_nuclideUri()).default.createRemoteUri('fb.com', '/usr/local');const remoteUriWithSpaces = (_nuclideUri || _load_nuclideUri()).default.createRemoteUri('fb.com', '/a b/c d');const remoteUriWithHashes = (_nuclideUri || _load_nuclideUri()).default.createRemoteUri('fb.co.uk', '/ab/#c.d #'); + const localArchiveUri = '/etc/file.zip!a'; - const remoteArchiveUri = nuclideUri.createRemoteUri( - 'fb.com', - '/file.zip!a.txt', - ); + const remoteArchiveUri = (_nuclideUri || _load_nuclideUri()).default.createRemoteUri( + 'fb.com', + '/file.zip!a.txt'); + const endsWithExclamationUri = '/module/!! WARNING !!'; const archiveSuffixUri = '/etc/file.zip!'; it('isRemote', () => { - expect(nuclideUri.isRemote('/')).toBe(false); - expect(nuclideUri.isRemote(remoteUri)).toBe(true); - expect(nuclideUri.isRemote(atomUri)).toBe(false); - expect(nuclideUri.isRemote(localArchiveUri)).toBe(false); - expect(nuclideUri.isRemote(remoteArchiveUri)).toBe(true); - expect(nuclideUri.isRemote(endsWithExclamationUri)).toBe(false); + expect((_nuclideUri || _load_nuclideUri()).default.isRemote('/')).toBe(false); + expect((_nuclideUri || _load_nuclideUri()).default.isRemote(remoteUri)).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isRemote(atomUri)).toBe(false); + expect((_nuclideUri || _load_nuclideUri()).default.isRemote(localArchiveUri)).toBe(false); + expect((_nuclideUri || _load_nuclideUri()).default.isRemote(remoteArchiveUri)).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isRemote(endsWithExclamationUri)).toBe(false); }); it('isLocal', () => { - expect(nuclideUri.isLocal('/')).toBe(true); - expect(nuclideUri.isLocal(remoteUri)).toBe(false); - expect(nuclideUri.isLocal('C:\\abc')).toBe(true); - expect(nuclideUri.isLocal(atomUri)).toBe(false); - expect(nuclideUri.isLocal(localArchiveUri)).toBe(true); - expect(nuclideUri.isLocal(remoteArchiveUri)).toBe(false); - expect(nuclideUri.isLocal(endsWithExclamationUri)).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isLocal('/')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isLocal(remoteUri)).toBe(false); + expect((_nuclideUri || _load_nuclideUri()).default.isLocal('C:\\abc')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isLocal(atomUri)).toBe(false); + expect((_nuclideUri || _load_nuclideUri()).default.isLocal(localArchiveUri)).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isLocal(remoteArchiveUri)).toBe(false); + expect((_nuclideUri || _load_nuclideUri()).default.isLocal(endsWithExclamationUri)).toBe(true); }); it('createRemoteUri', () => { @@ -58,710 +58,710 @@ describe('nuclide-uri', () => { }); it('join', () => { - expect(nuclideUri.join.bind(null, badRemoteUriNoPath, '../foo')).toThrow(); - expect(nuclideUri.join('/usr/local', 'bin')).toBe('/usr/local/bin'); - expect(nuclideUri.join(remoteUri, 'bin')).toBe( - 'nuclide://fb.com/usr/local/bin', - ); - expect(nuclideUri.join(localArchiveUri, 'b.txt')).toBe( - '/etc/file.zip!a/b.txt', - ); - expect(nuclideUri.join(endsWithExclamationUri, 'b.txt')).toBe( - '/module/!! WARNING !!/b.txt', - ); - expect(nuclideUri.join('/usr/local', '..')).toBe('/usr'); - expect(nuclideUri.join(remoteUri, '..')).toBe('nuclide://fb.com/usr'); - expect(() => nuclideUri.join(archiveSuffixUri)).toThrow(); + expect((_nuclideUri || _load_nuclideUri()).default.join.bind(null, badRemoteUriNoPath, '../foo')).toThrow(); + expect((_nuclideUri || _load_nuclideUri()).default.join('/usr/local', 'bin')).toBe('/usr/local/bin'); + expect((_nuclideUri || _load_nuclideUri()).default.join(remoteUri, 'bin')).toBe( + 'nuclide://fb.com/usr/local/bin'); + + expect((_nuclideUri || _load_nuclideUri()).default.join(localArchiveUri, 'b.txt')).toBe( + '/etc/file.zip!a/b.txt'); + + expect((_nuclideUri || _load_nuclideUri()).default.join(endsWithExclamationUri, 'b.txt')).toBe( + '/module/!! WARNING !!/b.txt'); + + expect((_nuclideUri || _load_nuclideUri()).default.join('/usr/local', '..')).toBe('/usr'); + expect((_nuclideUri || _load_nuclideUri()).default.join(remoteUri, '..')).toBe('nuclide://fb.com/usr'); + expect(() => (_nuclideUri || _load_nuclideUri()).default.join(archiveSuffixUri)).toThrow(); }); it('archiveJoin', () => { - expect(nuclideUri.archiveJoin('/file.zip', 'a.txt')).toBe( - '/file.zip!a.txt', - ); - expect(() => nuclideUri.archiveJoin(archiveSuffixUri, 'a.txt')).toThrow(); - expect(() => nuclideUri.archiveJoin('/dir', 'a.txt')).toThrow(); + expect((_nuclideUri || _load_nuclideUri()).default.archiveJoin('/file.zip', 'a.txt')).toBe( + '/file.zip!a.txt'); + + expect(() => (_nuclideUri || _load_nuclideUri()).default.archiveJoin(archiveSuffixUri, 'a.txt')).toThrow(); + expect(() => (_nuclideUri || _load_nuclideUri()).default.archiveJoin('/dir', 'a.txt')).toThrow(); }); describe('parsing remote', () => { it('handles simple paths', () => { - expect(nuclideUri.getHostname(remoteUri)).toBe('fb.com'); - expect(nuclideUri.getPath(remoteUri)).toBe('/usr/local'); + expect((_nuclideUri || _load_nuclideUri()).default.getHostname(remoteUri)).toBe('fb.com'); + expect((_nuclideUri || _load_nuclideUri()).default.getPath(remoteUri)).toBe('/usr/local'); }); it('does not encode space characters', () => { - expect(nuclideUri.getHostname(remoteUriWithSpaces)).toBe('fb.com'); - expect(nuclideUri.getPath(remoteUriWithSpaces)).toBe('/a b/c d'); + expect((_nuclideUri || _load_nuclideUri()).default.getHostname(remoteUriWithSpaces)).toBe('fb.com'); + expect((_nuclideUri || _load_nuclideUri()).default.getPath(remoteUriWithSpaces)).toBe('/a b/c d'); }); it('treats hash symbols as literals, part of the path', () => { - const parsedUri = nuclideUri.parse(remoteUriWithHashes); + const parsedUri = (_nuclideUri || _load_nuclideUri()).default.parse(remoteUriWithHashes); expect(parsedUri.hostname).toBe('fb.co.uk'); expect(parsedUri.path).toBe('/ab/#c.d #'); }); it('throws when given an illegal URI', () => { - expect(() => nuclideUri.getHostname(archiveSuffixUri)).toThrow(); - expect(() => nuclideUri.getPath(archiveSuffixUri)).toThrow(); - expect(() => nuclideUri.parse(archiveSuffixUri)).toThrow(); + expect(() => (_nuclideUri || _load_nuclideUri()).default.getHostname(archiveSuffixUri)).toThrow(); + expect(() => (_nuclideUri || _load_nuclideUri()).default.getPath(archiveSuffixUri)).toThrow(); + expect(() => (_nuclideUri || _load_nuclideUri()).default.parse(archiveSuffixUri)).toThrow(); }); }); it('parsing local', () => { - expect(() => nuclideUri.getHostname(localUri)).toThrow(); - expect(() => nuclideUri.getHostname(localArchiveUri)).toThrow(); - expect(nuclideUri.getPath(localUri)).toBe(localUri); - expect(nuclideUri.getPath(localArchiveUri)).toBe(localArchiveUri); - expect(nuclideUri.getPath(remoteArchiveUri)).toBe('/file.zip!a.txt'); - expect(nuclideUri.getPath(endsWithExclamationUri)).toBe( - endsWithExclamationUri, - ); - expect(() => nuclideUri.getPath('nuclide://host/archive.zip!')).toThrow(); - expect(() => nuclideUri.parseRemoteUri(localUri)).toThrow(); + expect(() => (_nuclideUri || _load_nuclideUri()).default.getHostname(localUri)).toThrow(); + expect(() => (_nuclideUri || _load_nuclideUri()).default.getHostname(localArchiveUri)).toThrow(); + expect((_nuclideUri || _load_nuclideUri()).default.getPath(localUri)).toBe(localUri); + expect((_nuclideUri || _load_nuclideUri()).default.getPath(localArchiveUri)).toBe(localArchiveUri); + expect((_nuclideUri || _load_nuclideUri()).default.getPath(remoteArchiveUri)).toBe('/file.zip!a.txt'); + expect((_nuclideUri || _load_nuclideUri()).default.getPath(endsWithExclamationUri)).toBe( + endsWithExclamationUri); + + expect(() => (_nuclideUri || _load_nuclideUri()).default.getPath('nuclide://host/archive.zip!')).toThrow(); + expect(() => (_nuclideUri || _load_nuclideUri()).default.parseRemoteUri(localUri)).toThrow(); }); it('basename', () => { - expect(nuclideUri.basename('/')).toBe(''); - expect(nuclideUri.basename('/abc')).toBe('abc'); - expect(nuclideUri.basename('/abc/')).toBe('abc'); - expect(nuclideUri.basename('/abc/def')).toBe('def'); - expect(nuclideUri.basename('/abc/def/')).toBe('def'); - - expect(nuclideUri.basename('nuclide://host/')).toBe(''); - expect(nuclideUri.basename('nuclide://host/abc')).toBe('abc'); - expect(nuclideUri.basename('nuclide://host/abc/')).toBe('abc'); - expect(nuclideUri.basename('nuclide://host/abc/def')).toBe('def'); - expect(nuclideUri.basename('nuclide://host/abc/def/')).toBe('def'); - expect(nuclideUri.basename('nuclide://host/a c/d f')).toBe('d f'); - - expect(nuclideUri.basename('/z.zip!abc')).toBe('abc'); - expect(nuclideUri.basename('/z.zip!abc/')).toBe('abc'); - expect(nuclideUri.basename('/z.zip!abc/def')).toBe('def'); - expect(nuclideUri.basename('/abc/def!ghi')).toBe('def!ghi'); - expect(nuclideUri.basename('/abc/def.txt!ghi')).toBe('def.txt!ghi'); - - expect(nuclideUri.basename('nuclide://host/z.zip!abc')).toBe('abc'); - expect(nuclideUri.basename('nuclide://host/z.zip!abc/')).toBe('abc'); - expect(nuclideUri.basename('nuclide://host/z.zip!abc/def')).toBe('def'); - - expect(nuclideUri.basename('C:\\')).toBe(''); - expect(nuclideUri.basename('C:\\abc')).toBe('abc'); - expect(nuclideUri.basename('C:\\abc\\')).toBe('abc'); - expect(nuclideUri.basename('C:\\abc\\def')).toBe('def'); - expect(nuclideUri.basename('C:\\abc\\def\\')).toBe('def'); - expect(nuclideUri.basename('\\abc\\def')).toBe('def'); - expect(nuclideUri.basename('\\abc\\def\\')).toBe('def'); - - expect(nuclideUri.basename('C:\\z.zip!abc')).toBe('abc'); - expect(nuclideUri.basename('C:\\z.zip!abc\\')).toBe('abc'); - expect(nuclideUri.basename('C:\\z.zip!abc\\def')).toBe('def'); - expect(nuclideUri.basename('C:\\abc\\def!ghi')).toBe('def!ghi'); - expect(nuclideUri.basename('C:\\abc\\def.txt!ghi')).toBe('def.txt!ghi'); - expect(nuclideUri.basename('\\z.zip!abc')).toBe('abc'); - expect(nuclideUri.basename('\\z.zip!abc\\')).toBe('abc'); - expect(nuclideUri.basename('\\z.zip!abc\\def')).toBe('def'); - expect(nuclideUri.basename('\\abc\\def!ghi')).toBe('def!ghi'); - expect(nuclideUri.basename('\\abc\\def.txt!ghi')).toBe('def.txt!ghi'); - - expect(() => nuclideUri.basename(archiveSuffixUri)).toThrow(); + expect((_nuclideUri || _load_nuclideUri()).default.basename('/')).toBe(''); + expect((_nuclideUri || _load_nuclideUri()).default.basename('/abc')).toBe('abc'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('/abc/')).toBe('abc'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('/abc/def')).toBe('def'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('/abc/def/')).toBe('def'); + + expect((_nuclideUri || _load_nuclideUri()).default.basename('nuclide://host/')).toBe(''); + expect((_nuclideUri || _load_nuclideUri()).default.basename('nuclide://host/abc')).toBe('abc'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('nuclide://host/abc/')).toBe('abc'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('nuclide://host/abc/def')).toBe('def'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('nuclide://host/abc/def/')).toBe('def'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('nuclide://host/a c/d f')).toBe('d f'); + + expect((_nuclideUri || _load_nuclideUri()).default.basename('/z.zip!abc')).toBe('abc'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('/z.zip!abc/')).toBe('abc'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('/z.zip!abc/def')).toBe('def'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('/abc/def!ghi')).toBe('def!ghi'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('/abc/def.txt!ghi')).toBe('def.txt!ghi'); + + expect((_nuclideUri || _load_nuclideUri()).default.basename('nuclide://host/z.zip!abc')).toBe('abc'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('nuclide://host/z.zip!abc/')).toBe('abc'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('nuclide://host/z.zip!abc/def')).toBe('def'); + + expect((_nuclideUri || _load_nuclideUri()).default.basename('C:\\')).toBe(''); + expect((_nuclideUri || _load_nuclideUri()).default.basename('C:\\abc')).toBe('abc'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('C:\\abc\\')).toBe('abc'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('C:\\abc\\def')).toBe('def'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('C:\\abc\\def\\')).toBe('def'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('\\abc\\def')).toBe('def'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('\\abc\\def\\')).toBe('def'); + + expect((_nuclideUri || _load_nuclideUri()).default.basename('C:\\z.zip!abc')).toBe('abc'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('C:\\z.zip!abc\\')).toBe('abc'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('C:\\z.zip!abc\\def')).toBe('def'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('C:\\abc\\def!ghi')).toBe('def!ghi'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('C:\\abc\\def.txt!ghi')).toBe('def.txt!ghi'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('\\z.zip!abc')).toBe('abc'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('\\z.zip!abc\\')).toBe('abc'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('\\z.zip!abc\\def')).toBe('def'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('\\abc\\def!ghi')).toBe('def!ghi'); + expect((_nuclideUri || _load_nuclideUri()).default.basename('\\abc\\def.txt!ghi')).toBe('def.txt!ghi'); + + expect(() => (_nuclideUri || _load_nuclideUri()).default.basename(archiveSuffixUri)).toThrow(); }); it('dirname', () => { - expect(nuclideUri.dirname('/')).toBe('/'); - expect(nuclideUri.dirname('/abc')).toBe('/'); - expect(nuclideUri.dirname('/abc/')).toBe('/'); - expect(nuclideUri.dirname('/abc/def')).toBe('/abc'); - expect(nuclideUri.dirname('/abc/def/')).toBe('/abc'); - - expect(nuclideUri.dirname('nuclide://host/')).toBe('nuclide://host/'); - expect(nuclideUri.dirname('nuclide://host/abc')).toBe('nuclide://host/'); - expect(nuclideUri.dirname('nuclide://host/abc/')).toBe('nuclide://host/'); - expect(nuclideUri.dirname('nuclide://host/abc/def')).toBe( - 'nuclide://host/abc', - ); - expect(nuclideUri.dirname('nuclide://host/abc/def/')).toBe( - 'nuclide://host/abc', - ); - expect(nuclideUri.dirname('nuclide://host/a c/d f')).toBe( - 'nuclide://host/a c', - ); - - expect(nuclideUri.dirname('/z.zip!abc')).toBe('/z.zip'); - expect(nuclideUri.dirname('/z.zip!abc/')).toBe('/z.zip'); - expect(nuclideUri.dirname('/z.zip!abc/def')).toBe('/z.zip!abc'); - expect(nuclideUri.dirname('/abc/def!ghi')).toBe('/abc'); - expect(nuclideUri.dirname('/abc/def.txt!ghi')).toBe('/abc'); - - expect(nuclideUri.dirname('nuclide://host/z.zip!abc')).toBe( - 'nuclide://host/z.zip', - ); - expect(nuclideUri.dirname('nuclide://host/z.zip!abc/')).toBe( - 'nuclide://host/z.zip', - ); - expect(nuclideUri.dirname('nuclide://host/z.zip!abc/def')).toBe( - 'nuclide://host/z.zip!abc', - ); - - expect(nuclideUri.dirname('C:\\')).toBe('C:\\'); - expect(nuclideUri.dirname('C:\\abc')).toBe('C:\\'); - expect(nuclideUri.dirname('C:\\abc\\')).toBe('C:\\'); - expect(nuclideUri.dirname('C:\\abc\\def')).toBe('C:\\abc'); - expect(nuclideUri.dirname('C:\\abc\\def\\')).toBe('C:\\abc'); - expect(nuclideUri.dirname('\\abc\\def')).toBe('\\abc'); - expect(nuclideUri.dirname('\\abc\\def\\')).toBe('\\abc'); - - expect(nuclideUri.dirname('C:\\z.zip!abc')).toBe('C:\\z.zip'); - expect(nuclideUri.dirname('C:\\z.zip!abc/')).toBe('C:\\z.zip'); - expect(nuclideUri.dirname('C:\\z.zip!abc/def')).toBe('C:\\z.zip!abc'); - expect(nuclideUri.dirname('C:\\abc\\def!ghi')).toBe('C:\\abc'); - expect(nuclideUri.dirname('C:\\abc\\def.txt!ghi')).toBe('C:\\abc'); - expect(nuclideUri.dirname('\\z.zip!abc')).toBe('\\z.zip'); - expect(nuclideUri.dirname('\\z.zip!abc/')).toBe('\\z.zip'); - expect(nuclideUri.dirname('\\z.zip!abc/def')).toBe('\\z.zip!abc'); - expect(nuclideUri.dirname('\\abc\\def!ghi')).toBe('\\abc'); - expect(nuclideUri.dirname('\\abc\\def.txt!ghi')).toBe('\\abc'); - - expect(() => nuclideUri.dirname(archiveSuffixUri)).toThrow(); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('/')).toBe('/'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('/abc')).toBe('/'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('/abc/')).toBe('/'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('/abc/def')).toBe('/abc'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('/abc/def/')).toBe('/abc'); + + expect((_nuclideUri || _load_nuclideUri()).default.dirname('nuclide://host/')).toBe('nuclide://host/'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('nuclide://host/abc')).toBe('nuclide://host/'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('nuclide://host/abc/')).toBe('nuclide://host/'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('nuclide://host/abc/def')).toBe( + 'nuclide://host/abc'); + + expect((_nuclideUri || _load_nuclideUri()).default.dirname('nuclide://host/abc/def/')).toBe( + 'nuclide://host/abc'); + + expect((_nuclideUri || _load_nuclideUri()).default.dirname('nuclide://host/a c/d f')).toBe( + 'nuclide://host/a c'); + + + expect((_nuclideUri || _load_nuclideUri()).default.dirname('/z.zip!abc')).toBe('/z.zip'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('/z.zip!abc/')).toBe('/z.zip'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('/z.zip!abc/def')).toBe('/z.zip!abc'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('/abc/def!ghi')).toBe('/abc'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('/abc/def.txt!ghi')).toBe('/abc'); + + expect((_nuclideUri || _load_nuclideUri()).default.dirname('nuclide://host/z.zip!abc')).toBe( + 'nuclide://host/z.zip'); + + expect((_nuclideUri || _load_nuclideUri()).default.dirname('nuclide://host/z.zip!abc/')).toBe( + 'nuclide://host/z.zip'); + + expect((_nuclideUri || _load_nuclideUri()).default.dirname('nuclide://host/z.zip!abc/def')).toBe( + 'nuclide://host/z.zip!abc'); + + + expect((_nuclideUri || _load_nuclideUri()).default.dirname('C:\\')).toBe('C:\\'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('C:\\abc')).toBe('C:\\'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('C:\\abc\\')).toBe('C:\\'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('C:\\abc\\def')).toBe('C:\\abc'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('C:\\abc\\def\\')).toBe('C:\\abc'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('\\abc\\def')).toBe('\\abc'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('\\abc\\def\\')).toBe('\\abc'); + + expect((_nuclideUri || _load_nuclideUri()).default.dirname('C:\\z.zip!abc')).toBe('C:\\z.zip'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('C:\\z.zip!abc/')).toBe('C:\\z.zip'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('C:\\z.zip!abc/def')).toBe('C:\\z.zip!abc'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('C:\\abc\\def!ghi')).toBe('C:\\abc'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('C:\\abc\\def.txt!ghi')).toBe('C:\\abc'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('\\z.zip!abc')).toBe('\\z.zip'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('\\z.zip!abc/')).toBe('\\z.zip'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('\\z.zip!abc/def')).toBe('\\z.zip!abc'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('\\abc\\def!ghi')).toBe('\\abc'); + expect((_nuclideUri || _load_nuclideUri()).default.dirname('\\abc\\def.txt!ghi')).toBe('\\abc'); + + expect(() => (_nuclideUri || _load_nuclideUri()).default.dirname(archiveSuffixUri)).toThrow(); }); it('extname', () => { - expect(nuclideUri.extname('/abc')).toBe(''); - expect(nuclideUri.extname('/abc.')).toBe('.'); - expect(nuclideUri.extname('/abc.txt')).toBe('.txt'); - expect(nuclideUri.extname('/abc/def.html')).toBe('.html'); - expect(nuclideUri.extname('/abc/def/')).toBe(''); - expect(nuclideUri.extname('/abc/def.dir/')).toBe('.dir'); - - expect(nuclideUri.extname('nuclide://host/')).toBe(''); - expect(nuclideUri.extname('nuclide://host/abc')).toBe(''); - expect(nuclideUri.extname('nuclide://host/abc.txt')).toBe('.txt'); - expect(nuclideUri.extname('nuclide://host/abc.')).toBe('.'); - expect(nuclideUri.extname('nuclide://host/abc/')).toBe(''); - expect(nuclideUri.extname('nuclide://host/abc/def')).toBe(''); - expect(nuclideUri.extname('nuclide://host/abc/def.js')).toBe('.js'); - - expect(nuclideUri.extname('/z.zip!abc')).toBe(''); - expect(nuclideUri.extname('/z.zip!abc.zip')).toBe('.zip'); - expect(nuclideUri.extname('/abc.txt!def')).toBe('.txt!def'); - - expect(nuclideUri.extname('C:\\')).toBe(''); - expect(nuclideUri.extname('C:\\abc')).toBe(''); - expect(nuclideUri.extname('C:\\abc\\')).toBe(''); - expect(nuclideUri.extname('C:\\abc.')).toBe('.'); - expect(nuclideUri.extname('C:\\abc.js')).toBe('.js'); - expect(nuclideUri.extname('C:\\abc\\def')).toBe(''); - expect(nuclideUri.extname('C:\\abc\\def\\')).toBe(''); - expect(nuclideUri.extname('C:\\abc\\def.')).toBe('.'); - expect(nuclideUri.extname('C:\\abc\\def.html')).toBe('.html'); - expect(nuclideUri.extname('\\abc\\def')).toBe(''); - expect(nuclideUri.extname('\\abc\\def.dir\\')).toBe('.dir'); - expect(nuclideUri.extname('\\abc\\def.')).toBe('.'); - expect(nuclideUri.extname('\\abc\\def.xml')).toBe('.xml'); - - expect(nuclideUri.extname('C:\\z.zip!abc')).toBe(''); - expect(nuclideUri.extname('C:\\z.zip!abc.zip')).toBe('.zip'); - expect(nuclideUri.extname('C:\\abc.txt!def')).toBe('.txt!def'); - expect(nuclideUri.extname('\\z.zip!abc')).toBe(''); - expect(nuclideUri.extname('\\z.zip!abc.zip')).toBe('.zip'); - expect(nuclideUri.extname('\\abc.txt!def')).toBe('.txt!def'); - - expect(() => nuclideUri.extname(archiveSuffixUri)).toThrow(); + expect((_nuclideUri || _load_nuclideUri()).default.extname('/abc')).toBe(''); + expect((_nuclideUri || _load_nuclideUri()).default.extname('/abc.')).toBe('.'); + expect((_nuclideUri || _load_nuclideUri()).default.extname('/abc.txt')).toBe('.txt'); + expect((_nuclideUri || _load_nuclideUri()).default.extname('/abc/def.html')).toBe('.html'); + expect((_nuclideUri || _load_nuclideUri()).default.extname('/abc/def/')).toBe(''); + expect((_nuclideUri || _load_nuclideUri()).default.extname('/abc/def.dir/')).toBe('.dir'); + + expect((_nuclideUri || _load_nuclideUri()).default.extname('nuclide://host/')).toBe(''); + expect((_nuclideUri || _load_nuclideUri()).default.extname('nuclide://host/abc')).toBe(''); + expect((_nuclideUri || _load_nuclideUri()).default.extname('nuclide://host/abc.txt')).toBe('.txt'); + expect((_nuclideUri || _load_nuclideUri()).default.extname('nuclide://host/abc.')).toBe('.'); + expect((_nuclideUri || _load_nuclideUri()).default.extname('nuclide://host/abc/')).toBe(''); + expect((_nuclideUri || _load_nuclideUri()).default.extname('nuclide://host/abc/def')).toBe(''); + expect((_nuclideUri || _load_nuclideUri()).default.extname('nuclide://host/abc/def.js')).toBe('.js'); + + expect((_nuclideUri || _load_nuclideUri()).default.extname('/z.zip!abc')).toBe(''); + expect((_nuclideUri || _load_nuclideUri()).default.extname('/z.zip!abc.zip')).toBe('.zip'); + expect((_nuclideUri || _load_nuclideUri()).default.extname('/abc.txt!def')).toBe('.txt!def'); + + expect((_nuclideUri || _load_nuclideUri()).default.extname('C:\\')).toBe(''); + expect((_nuclideUri || _load_nuclideUri()).default.extname('C:\\abc')).toBe(''); + expect((_nuclideUri || _load_nuclideUri()).default.extname('C:\\abc\\')).toBe(''); + expect((_nuclideUri || _load_nuclideUri()).default.extname('C:\\abc.')).toBe('.'); + expect((_nuclideUri || _load_nuclideUri()).default.extname('C:\\abc.js')).toBe('.js'); + expect((_nuclideUri || _load_nuclideUri()).default.extname('C:\\abc\\def')).toBe(''); + expect((_nuclideUri || _load_nuclideUri()).default.extname('C:\\abc\\def\\')).toBe(''); + expect((_nuclideUri || _load_nuclideUri()).default.extname('C:\\abc\\def.')).toBe('.'); + expect((_nuclideUri || _load_nuclideUri()).default.extname('C:\\abc\\def.html')).toBe('.html'); + expect((_nuclideUri || _load_nuclideUri()).default.extname('\\abc\\def')).toBe(''); + expect((_nuclideUri || _load_nuclideUri()).default.extname('\\abc\\def.dir\\')).toBe('.dir'); + expect((_nuclideUri || _load_nuclideUri()).default.extname('\\abc\\def.')).toBe('.'); + expect((_nuclideUri || _load_nuclideUri()).default.extname('\\abc\\def.xml')).toBe('.xml'); + + expect((_nuclideUri || _load_nuclideUri()).default.extname('C:\\z.zip!abc')).toBe(''); + expect((_nuclideUri || _load_nuclideUri()).default.extname('C:\\z.zip!abc.zip')).toBe('.zip'); + expect((_nuclideUri || _load_nuclideUri()).default.extname('C:\\abc.txt!def')).toBe('.txt!def'); + expect((_nuclideUri || _load_nuclideUri()).default.extname('\\z.zip!abc')).toBe(''); + expect((_nuclideUri || _load_nuclideUri()).default.extname('\\z.zip!abc.zip')).toBe('.zip'); + expect((_nuclideUri || _load_nuclideUri()).default.extname('\\abc.txt!def')).toBe('.txt!def'); + + expect(() => (_nuclideUri || _load_nuclideUri()).default.extname(archiveSuffixUri)).toThrow(); }); it('getParent', () => { - expect(nuclideUri.getParent(localUri)).toBe('/usr/local'); - expect(nuclideUri.getParent(remoteUri)).toBe('nuclide://fb.com/usr'); - expect(nuclideUri.getParent('/etc/file.zip!a')).toBe('/etc/file.zip'); - expect(nuclideUri.getParent(localArchiveUri)).toBe('/etc/file.zip'); - expect(nuclideUri.getParent(remoteArchiveUri)).toBe( - 'nuclide://fb.com/file.zip', - ); - expect(nuclideUri.getParent(endsWithExclamationUri)).toBe('/module'); - expect(nuclideUri.getParent('/abc/def!ghi')).toBe('/abc'); - expect(() => nuclideUri.getParent(archiveSuffixUri)).toThrow(); + expect((_nuclideUri || _load_nuclideUri()).default.getParent(localUri)).toBe('/usr/local'); + expect((_nuclideUri || _load_nuclideUri()).default.getParent(remoteUri)).toBe('nuclide://fb.com/usr'); + expect((_nuclideUri || _load_nuclideUri()).default.getParent('/etc/file.zip!a')).toBe('/etc/file.zip'); + expect((_nuclideUri || _load_nuclideUri()).default.getParent(localArchiveUri)).toBe('/etc/file.zip'); + expect((_nuclideUri || _load_nuclideUri()).default.getParent(remoteArchiveUri)).toBe( + 'nuclide://fb.com/file.zip'); + + expect((_nuclideUri || _load_nuclideUri()).default.getParent(endsWithExclamationUri)).toBe('/module'); + expect((_nuclideUri || _load_nuclideUri()).default.getParent('/abc/def!ghi')).toBe('/abc'); + expect(() => (_nuclideUri || _load_nuclideUri()).default.getParent(archiveSuffixUri)).toThrow(); }); it('contains', () => { - expect(nuclideUri.contains('/usr/local', localUri)).toBe(true); - expect(nuclideUri.contains('nuclide://fb.com/usr', remoteUri)).toBe(true); - expect(nuclideUri.contains('/foo/bar/', '/foo/bar/abc.txt')).toBe(true); - expect(nuclideUri.contains('/foo/bar', '/foo/bar/')).toBe(true); - expect(nuclideUri.contains('/foo/bar/', '/foo/bar/')).toBe(true); - expect(nuclideUri.contains('/foo/bar/', '/foo/bar')).toBe(true); - - expect(nuclideUri.contains('/z.zip', '/z.zip!abc')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.contains('/usr/local', localUri)).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.contains('nuclide://fb.com/usr', remoteUri)).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.contains('/foo/bar/', '/foo/bar/abc.txt')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.contains('/foo/bar', '/foo/bar/')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.contains('/foo/bar/', '/foo/bar/')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.contains('/foo/bar/', '/foo/bar')).toBe(true); + + expect((_nuclideUri || _load_nuclideUri()).default.contains('/z.zip', '/z.zip!abc')).toBe(true); expect( - nuclideUri.contains( - 'nuclide://fb.com/z.zip', - 'nuclide://fb.com/z.zip!abc', - ), - ).toBe(true); - expect(nuclideUri.contains('/z.zip!abc', '/z.zip!abc/def')).toBe(true); + (_nuclideUri || _load_nuclideUri()).default.contains( + 'nuclide://fb.com/z.zip', + 'nuclide://fb.com/z.zip!abc')). + + toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.contains('/z.zip!abc', '/z.zip!abc/def')).toBe(true); expect( - nuclideUri.contains( - 'nuclide://fb.com/z.zip!abc', - 'nuclide://fb.com/z.zip!abc/def', - ), - ).toBe(true); - expect(nuclideUri.contains('/abc', '/abc!def')).toBe(false); - - expect(() => nuclideUri.contains(archiveSuffixUri, '/foo/bar')).toThrow(); - expect(() => nuclideUri.contains('/foo/bar', archiveSuffixUri)).toThrow(); + (_nuclideUri || _load_nuclideUri()).default.contains( + 'nuclide://fb.com/z.zip!abc', + 'nuclide://fb.com/z.zip!abc/def')). + + toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.contains('/abc', '/abc!def')).toBe(false); + + expect(() => (_nuclideUri || _load_nuclideUri()).default.contains(archiveSuffixUri, '/foo/bar')).toThrow(); + expect(() => (_nuclideUri || _load_nuclideUri()).default.contains('/foo/bar', archiveSuffixUri)).toThrow(); }); it('collapse', () => { - expect(nuclideUri.collapse(['/a', '/b'])).toEqual(['/a', '/b']); - expect(nuclideUri.collapse(['/a/b/c/d', '/a', '/a/b'])).toEqual(['/a']); - expect(nuclideUri.collapse(['/a', '/a/b', '/a/b/c'])).toEqual(['/a']); + expect((_nuclideUri || _load_nuclideUri()).default.collapse(['/a', '/b'])).toEqual(['/a', '/b']); + expect((_nuclideUri || _load_nuclideUri()).default.collapse(['/a/b/c/d', '/a', '/a/b'])).toEqual(['/a']); + expect((_nuclideUri || _load_nuclideUri()).default.collapse(['/a', '/a/b', '/a/b/c'])).toEqual(['/a']); expect( - nuclideUri.collapse(['/a/b.zip', '/a/b.zip!c', '/a/b.zip!c/d']), - ).toEqual(['/a/b.zip']); + (_nuclideUri || _load_nuclideUri()).default.collapse(['/a/b.zip', '/a/b.zip!c', '/a/b.zip!c/d'])). + toEqual(['/a/b.zip']); expect( - nuclideUri.collapse(['/a/b.zip!c', '/a/b.zip!c/d', '/a/b.zip!c/d/e']), - ).toEqual(['/a/b.zip!c']); + (_nuclideUri || _load_nuclideUri()).default.collapse(['/a/b.zip!c', '/a/b.zip!c/d', '/a/b.zip!c/d/e'])). + toEqual(['/a/b.zip!c']); expect( - nuclideUri.collapse(['/a/c', '/a/c/d', '/a/b', '/a/b/c/d/e']), - ).toEqual(['/a/c', '/a/b']); - expect(nuclideUri.collapse(['/a/be', '/a/b'])).toEqual(['/a/be', '/a/b']); + (_nuclideUri || _load_nuclideUri()).default.collapse(['/a/c', '/a/c/d', '/a/b', '/a/b/c/d/e'])). + toEqual(['/a/c', '/a/b']); + expect((_nuclideUri || _load_nuclideUri()).default.collapse(['/a/be', '/a/b'])).toEqual(['/a/be', '/a/b']); expect( - nuclideUri.collapse([ - 'nuclide://fb.com/usr/local', - 'nuclide://fb.com/usr/local/test', - 'nuclide://facebook.com/usr/local/test', - ]), - ).toEqual([ - 'nuclide://fb.com/usr/local', - 'nuclide://facebook.com/usr/local/test', - ]); + (_nuclideUri || _load_nuclideUri()).default.collapse([ + 'nuclide://fb.com/usr/local', + 'nuclide://fb.com/usr/local/test', + 'nuclide://facebook.com/usr/local/test'])). + + toEqual([ + 'nuclide://fb.com/usr/local', + 'nuclide://facebook.com/usr/local/test']); + }); it('normalize', () => { - expect(nuclideUri.normalize(localUri)).toBe(localUri); - expect(nuclideUri.normalize(remoteUri)).toBe(remoteUri); - expect(nuclideUri.normalize.bind(null, badRemoteUriNoPath)).toThrow(); - expect(nuclideUri.normalize('/usr/local/..')).toBe('/usr'); - expect(nuclideUri.normalize('nuclide://fb.com/usr/local/..')).toBe( - 'nuclide://fb.com/usr', - ); - expect(nuclideUri.normalize('/a b/c d/..')).toBe('/a b'); - expect(nuclideUri.normalize('/a/b.zip!c/..')).toBe('/a/b.zip'); - expect(nuclideUri.normalize('/a/b.zip!c/d/../../..')).toBe('/a'); - expect(nuclideUri.normalize('/a/b!c/..')).toBe('/a'); - expect(() => nuclideUri.normalize(archiveSuffixUri)).toThrow(); + expect((_nuclideUri || _load_nuclideUri()).default.normalize(localUri)).toBe(localUri); + expect((_nuclideUri || _load_nuclideUri()).default.normalize(remoteUri)).toBe(remoteUri); + expect((_nuclideUri || _load_nuclideUri()).default.normalize.bind(null, badRemoteUriNoPath)).toThrow(); + expect((_nuclideUri || _load_nuclideUri()).default.normalize('/usr/local/..')).toBe('/usr'); + expect((_nuclideUri || _load_nuclideUri()).default.normalize('nuclide://fb.com/usr/local/..')).toBe( + 'nuclide://fb.com/usr'); + + expect((_nuclideUri || _load_nuclideUri()).default.normalize('/a b/c d/..')).toBe('/a b'); + expect((_nuclideUri || _load_nuclideUri()).default.normalize('/a/b.zip!c/..')).toBe('/a/b.zip'); + expect((_nuclideUri || _load_nuclideUri()).default.normalize('/a/b.zip!c/d/../../..')).toBe('/a'); + expect((_nuclideUri || _load_nuclideUri()).default.normalize('/a/b!c/..')).toBe('/a'); + expect(() => (_nuclideUri || _load_nuclideUri()).default.normalize(archiveSuffixUri)).toThrow(); }); it('relative', () => { - expect(() => nuclideUri.relative(localUri, remoteUri)).toThrow(); - expect(nuclideUri.relative(nuclideUri.dirname(remoteUri), remoteUri)).toBe( - 'local', - ); - expect(nuclideUri.relative(remoteUri, nuclideUri.dirname(remoteUri))).toBe( - '..', - ); + expect(() => (_nuclideUri || _load_nuclideUri()).default.relative(localUri, remoteUri)).toThrow(); + expect((_nuclideUri || _load_nuclideUri()).default.relative((_nuclideUri || _load_nuclideUri()).default.dirname(remoteUri), remoteUri)).toBe( + 'local'); + + expect((_nuclideUri || _load_nuclideUri()).default.relative(remoteUri, (_nuclideUri || _load_nuclideUri()).default.dirname(remoteUri))).toBe( + '..'); + expect( - nuclideUri.relative( - nuclideUri.dirname(remoteUriWithSpaces), - remoteUriWithSpaces, - ), - ).toBe('c d'); + (_nuclideUri || _load_nuclideUri()).default.relative( + (_nuclideUri || _load_nuclideUri()).default.dirname(remoteUriWithSpaces), + remoteUriWithSpaces)). + + toBe('c d'); expect( - nuclideUri.relative( - remoteUriWithSpaces, - nuclideUri.dirname(remoteUriWithSpaces), - ), - ).toBe('..'); - expect(nuclideUri.relative(nuclideUri.dirname(localUri), localUri)).toBe( - 'file', - ); - expect(nuclideUri.relative(localUri, nuclideUri.dirname(localUri))).toBe( - '..', - ); + (_nuclideUri || _load_nuclideUri()).default.relative( + remoteUriWithSpaces, + (_nuclideUri || _load_nuclideUri()).default.dirname(remoteUriWithSpaces))). + + toBe('..'); + expect((_nuclideUri || _load_nuclideUri()).default.relative((_nuclideUri || _load_nuclideUri()).default.dirname(localUri), localUri)).toBe( + 'file'); + + expect((_nuclideUri || _load_nuclideUri()).default.relative(localUri, (_nuclideUri || _load_nuclideUri()).default.dirname(localUri))).toBe( + '..'); + expect( - nuclideUri.relative(nuclideUri.dirname(localArchiveUri), localArchiveUri), - ).toBe('a'); + (_nuclideUri || _load_nuclideUri()).default.relative((_nuclideUri || _load_nuclideUri()).default.dirname(localArchiveUri), localArchiveUri)). + toBe('a'); expect( - nuclideUri.relative(localArchiveUri, nuclideUri.dirname(localArchiveUri)), - ).toBe('..'); + (_nuclideUri || _load_nuclideUri()).default.relative(localArchiveUri, (_nuclideUri || _load_nuclideUri()).default.dirname(localArchiveUri))). + toBe('..'); expect( - nuclideUri.relative( - nuclideUri.dirname(endsWithExclamationUri), - endsWithExclamationUri, - ), - ).toBe('!! WARNING !!'); + (_nuclideUri || _load_nuclideUri()).default.relative( + (_nuclideUri || _load_nuclideUri()).default.dirname(endsWithExclamationUri), + endsWithExclamationUri)). + + toBe('!! WARNING !!'); expect( - nuclideUri.relative( - endsWithExclamationUri, - nuclideUri.dirname(endsWithExclamationUri), - ), - ).toBe('..'); - expect(nuclideUri.relative('/a/b.zip!c', '/a/b.zip!d')).toBe('../d'); - expect(nuclideUri.relative('/a/b!c', '/a/b!d')).toBe('../b!d'); - expect(() => nuclideUri.relative(archiveSuffixUri, 'foo')).toThrow(); + (_nuclideUri || _load_nuclideUri()).default.relative( + endsWithExclamationUri, + (_nuclideUri || _load_nuclideUri()).default.dirname(endsWithExclamationUri))). + + toBe('..'); + expect((_nuclideUri || _load_nuclideUri()).default.relative('/a/b.zip!c', '/a/b.zip!d')).toBe('../d'); + expect((_nuclideUri || _load_nuclideUri()).default.relative('/a/b!c', '/a/b!d')).toBe('../b!d'); + expect(() => (_nuclideUri || _load_nuclideUri()).default.relative(archiveSuffixUri, 'foo')).toThrow(); }); it('nuclideUriToDisplayString', () => { - expect(nuclideUri.nuclideUriToDisplayString(localUri)).toBe(localUri); - expect(nuclideUri.nuclideUriToDisplayString(remoteUri)).toBe( - 'fb.com:/usr/local', - ); - expect(nuclideUri.nuclideUriToDisplayString(localArchiveUri)).toBe( - '/etc/file.zip!a', - ); - expect(nuclideUri.nuclideUriToDisplayString(remoteArchiveUri)).toBe( - 'fb.com:/file.zip!a.txt', - ); - expect(nuclideUri.nuclideUriToDisplayString(endsWithExclamationUri)).toBe( - '/module/!! WARNING !!', - ); + expect((_nuclideUri || _load_nuclideUri()).default.nuclideUriToDisplayString(localUri)).toBe(localUri); + expect((_nuclideUri || _load_nuclideUri()).default.nuclideUriToDisplayString(remoteUri)).toBe( + 'fb.com:/usr/local'); + + expect((_nuclideUri || _load_nuclideUri()).default.nuclideUriToDisplayString(localArchiveUri)).toBe( + '/etc/file.zip!a'); + + expect((_nuclideUri || _load_nuclideUri()).default.nuclideUriToDisplayString(remoteArchiveUri)).toBe( + 'fb.com:/file.zip!a.txt'); + + expect((_nuclideUri || _load_nuclideUri()).default.nuclideUriToDisplayString(endsWithExclamationUri)).toBe( + '/module/!! WARNING !!'); + expect(() => - nuclideUri.nuclideUriToDisplayString(archiveSuffixUri), - ).toThrow(); + (_nuclideUri || _load_nuclideUri()).default.nuclideUriToDisplayString(archiveSuffixUri)). + toThrow(); }); describe('isRoot', () => { - it('plain posix root', () => expect(nuclideUri.isRoot('/')).toBe(true)); - it('double root', () => expect(nuclideUri.isRoot('//')).toBe(false)); - it('/abc', () => expect(nuclideUri.isRoot('/abc')).toBe(false)); - it('abc', () => expect(nuclideUri.isRoot('abc')).toBe(false)); - it('abc/def', () => expect(nuclideUri.isRoot('abc/def')).toBe(false)); + it('plain posix root', () => expect((_nuclideUri || _load_nuclideUri()).default.isRoot('/')).toBe(true)); + it('double root', () => expect((_nuclideUri || _load_nuclideUri()).default.isRoot('//')).toBe(false)); + it('/abc', () => expect((_nuclideUri || _load_nuclideUri()).default.isRoot('/abc')).toBe(false)); + it('abc', () => expect((_nuclideUri || _load_nuclideUri()).default.isRoot('abc')).toBe(false)); + it('abc/def', () => expect((_nuclideUri || _load_nuclideUri()).default.isRoot('abc/def')).toBe(false)); it('/file.zip!', () => - expect(() => nuclideUri.isRoot('/file.zip!')).toThrow()); + expect(() => (_nuclideUri || _load_nuclideUri()).default.isRoot('/file.zip!')).toThrow()); it('/file.zip!abc', () => - expect(nuclideUri.isRoot('/file.zip!abc')).toBe(false)); + expect((_nuclideUri || _load_nuclideUri()).default.isRoot('/file.zip!abc')).toBe(false)); it('remote root', () => - expect(nuclideUri.isRoot('nuclide://host/')).toBe(true)); + expect((_nuclideUri || _load_nuclideUri()).default.isRoot('nuclide://host/')).toBe(true)); it('remote root with port', () => - expect(nuclideUri.isRoot('nuclide://host/')).toBe(true)); + expect((_nuclideUri || _load_nuclideUri()).default.isRoot('nuclide://host/')).toBe(true)); it('remote non-root', () => - expect(nuclideUri.isRoot('nuclide://host/abc')).toBe(false)); + expect((_nuclideUri || _load_nuclideUri()).default.isRoot('nuclide://host/abc')).toBe(false)); it('remote non-root no port', () => { - expect(nuclideUri.isRoot('nuclide://host/abc')).toBe(false); + expect((_nuclideUri || _load_nuclideUri()).default.isRoot('nuclide://host/abc')).toBe(false); }); - it('win diskless root', () => expect(nuclideUri.isRoot('\\')).toBe(true)); + it('win diskless root', () => expect((_nuclideUri || _load_nuclideUri()).default.isRoot('\\')).toBe(true)); it('win diskless double root', () => - expect(nuclideUri.isRoot('\\\\')).toBe(false)); + expect((_nuclideUri || _load_nuclideUri()).default.isRoot('\\\\')).toBe(false)); it('win diskless non-root', () => - expect(nuclideUri.isRoot('\\abc')).toBe(false)); - it('win diskful root', () => expect(nuclideUri.isRoot('C:\\')).toBe(true)); + expect((_nuclideUri || _load_nuclideUri()).default.isRoot('\\abc')).toBe(false)); + it('win diskful root', () => expect((_nuclideUri || _load_nuclideUri()).default.isRoot('C:\\')).toBe(true)); it('win diskful double root', () => - expect(nuclideUri.isRoot('C:\\\\')).toBe(false)); + expect((_nuclideUri || _load_nuclideUri()).default.isRoot('C:\\\\')).toBe(false)); it('win diskful non-root', () => - expect(nuclideUri.isRoot('C:\\abc')).toBe(false)); + expect((_nuclideUri || _load_nuclideUri()).default.isRoot('C:\\abc')).toBe(false)); - it('win relative', () => expect(nuclideUri.isRoot('abc\\def')).toBe(false)); + it('win relative', () => expect((_nuclideUri || _load_nuclideUri()).default.isRoot('abc\\def')).toBe(false)); it('throws on illegal URIs', () => { - expect(() => nuclideUri.basename(archiveSuffixUri)).toThrow(); + expect(() => (_nuclideUri || _load_nuclideUri()).default.basename(archiveSuffixUri)).toThrow(); }); }); it('adds a proper suffix when needed', () => { - expect(nuclideUri.ensureTrailingSeparator('/')).toBe('/'); - expect(nuclideUri.ensureTrailingSeparator('/abc')).toBe('/abc/'); - expect(nuclideUri.ensureTrailingSeparator('/abc/')).toBe('/abc/'); - expect(nuclideUri.ensureTrailingSeparator('/abc/def')).toBe('/abc/def/'); - expect(nuclideUri.ensureTrailingSeparator('/abc/def/')).toBe('/abc/def/'); - expect(nuclideUri.ensureTrailingSeparator('nuclide://host')).toBe( - 'nuclide://host/', - ); - expect(nuclideUri.ensureTrailingSeparator('nuclide://host/')).toBe( - 'nuclide://host/', - ); - expect(nuclideUri.ensureTrailingSeparator('nuclide://host/abc')).toBe( - 'nuclide://host/abc/', - ); - expect(nuclideUri.ensureTrailingSeparator('nuclide://host/abc/def')).toBe( - 'nuclide://host/abc/def/', - ); - expect(nuclideUri.ensureTrailingSeparator('nuclide://host/abc/def/')).toBe( - 'nuclide://host/abc/def/', - ); - expect(nuclideUri.ensureTrailingSeparator('C:\\')).toBe('C:\\'); - expect(nuclideUri.ensureTrailingSeparator('C:\\abc')).toBe('C:\\abc\\'); - expect(nuclideUri.ensureTrailingSeparator('C:\\abc\\')).toBe('C:\\abc\\'); - expect(nuclideUri.ensureTrailingSeparator('C:\\abc\\def')).toBe( - 'C:\\abc\\def\\', - ); - expect(nuclideUri.ensureTrailingSeparator('C:\\abc\\def\\')).toBe( - 'C:\\abc\\def\\', - ); - expect(nuclideUri.ensureTrailingSeparator('\\abc\\def')).toBe( - '\\abc\\def\\', - ); - expect(nuclideUri.ensureTrailingSeparator('\\abc\\def\\')).toBe( - '\\abc\\def\\', - ); + expect((_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator('/')).toBe('/'); + expect((_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator('/abc')).toBe('/abc/'); + expect((_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator('/abc/')).toBe('/abc/'); + expect((_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator('/abc/def')).toBe('/abc/def/'); + expect((_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator('/abc/def/')).toBe('/abc/def/'); + expect((_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator('nuclide://host')).toBe( + 'nuclide://host/'); + + expect((_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator('nuclide://host/')).toBe( + 'nuclide://host/'); + + expect((_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator('nuclide://host/abc')).toBe( + 'nuclide://host/abc/'); + + expect((_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator('nuclide://host/abc/def')).toBe( + 'nuclide://host/abc/def/'); + + expect((_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator('nuclide://host/abc/def/')).toBe( + 'nuclide://host/abc/def/'); + + expect((_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator('C:\\')).toBe('C:\\'); + expect((_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator('C:\\abc')).toBe('C:\\abc\\'); + expect((_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator('C:\\abc\\')).toBe('C:\\abc\\'); + expect((_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator('C:\\abc\\def')).toBe( + 'C:\\abc\\def\\'); + + expect((_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator('C:\\abc\\def\\')).toBe( + 'C:\\abc\\def\\'); + + expect((_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator('\\abc\\def')).toBe( + '\\abc\\def\\'); + + expect((_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator('\\abc\\def\\')).toBe( + '\\abc\\def\\'); + expect(() => - nuclideUri.ensureTrailingSeparator(archiveSuffixUri), - ).toThrow(); + (_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator(archiveSuffixUri)). + toThrow(); }); it('properly removes suffix when needed', () => { - expect(nuclideUri.trimTrailingSeparator('/')).toBe('/'); - expect(nuclideUri.trimTrailingSeparator('//')).toBe('/'); - expect(nuclideUri.trimTrailingSeparator('/abc')).toBe('/abc'); - expect(nuclideUri.trimTrailingSeparator('/abc/')).toBe('/abc'); - expect(nuclideUri.trimTrailingSeparator('/abc/def')).toBe('/abc/def'); - expect(nuclideUri.trimTrailingSeparator('/abc/def/')).toBe('/abc/def'); - expect(nuclideUri.trimTrailingSeparator('nuclide://host/')).toBe( - 'nuclide://host/', - ); - expect(nuclideUri.trimTrailingSeparator('nuclide://host//')).toBe( - 'nuclide://host/', - ); - expect(nuclideUri.trimTrailingSeparator('nuclide://host/')).toBe( - 'nuclide://host/', - ); - expect(nuclideUri.trimTrailingSeparator('nuclide://host//')).toBe( - 'nuclide://host/', - ); - expect(nuclideUri.trimTrailingSeparator('nuclide://host/abc')).toBe( - 'nuclide://host/abc', - ); - expect(nuclideUri.trimTrailingSeparator('nuclide://host/abc/')).toBe( - 'nuclide://host/abc', - ); - expect(nuclideUri.trimTrailingSeparator('nuclide://host/abc/def')).toBe( - 'nuclide://host/abc/def', - ); - expect(nuclideUri.trimTrailingSeparator('nuclide://host/abc/def/')).toBe( - 'nuclide://host/abc/def', - ); - expect(nuclideUri.trimTrailingSeparator('C:\\')).toBe('C:\\'); - expect(nuclideUri.trimTrailingSeparator('C:\\\\')).toBe('C:\\'); - expect(nuclideUri.trimTrailingSeparator('C:\\abc')).toBe('C:\\abc'); - expect(nuclideUri.trimTrailingSeparator('C:\\abc\\')).toBe('C:\\abc'); - expect(nuclideUri.trimTrailingSeparator('C:\\abc\\def')).toBe( - 'C:\\abc\\def', - ); - expect(nuclideUri.trimTrailingSeparator('C:\\abc\\def\\')).toBe( - 'C:\\abc\\def', - ); - expect(nuclideUri.trimTrailingSeparator('\\')).toBe('\\'); - expect(nuclideUri.trimTrailingSeparator('\\\\')).toBe('\\'); - expect(nuclideUri.trimTrailingSeparator('\\abc\\def')).toBe('\\abc\\def'); - expect(nuclideUri.trimTrailingSeparator('\\abc\\def\\')).toBe('\\abc\\def'); - expect(() => nuclideUri.trimTrailingSeparator(archiveSuffixUri)).toThrow(); + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('/')).toBe('/'); + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('//')).toBe('/'); + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('/abc')).toBe('/abc'); + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('/abc/')).toBe('/abc'); + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('/abc/def')).toBe('/abc/def'); + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('/abc/def/')).toBe('/abc/def'); + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('nuclide://host/')).toBe( + 'nuclide://host/'); + + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('nuclide://host//')).toBe( + 'nuclide://host/'); + + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('nuclide://host/')).toBe( + 'nuclide://host/'); + + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('nuclide://host//')).toBe( + 'nuclide://host/'); + + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('nuclide://host/abc')).toBe( + 'nuclide://host/abc'); + + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('nuclide://host/abc/')).toBe( + 'nuclide://host/abc'); + + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('nuclide://host/abc/def')).toBe( + 'nuclide://host/abc/def'); + + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('nuclide://host/abc/def/')).toBe( + 'nuclide://host/abc/def'); + + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('C:\\')).toBe('C:\\'); + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('C:\\\\')).toBe('C:\\'); + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('C:\\abc')).toBe('C:\\abc'); + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('C:\\abc\\')).toBe('C:\\abc'); + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('C:\\abc\\def')).toBe( + 'C:\\abc\\def'); + + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('C:\\abc\\def\\')).toBe( + 'C:\\abc\\def'); + + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('\\')).toBe('\\'); + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('\\\\')).toBe('\\'); + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('\\abc\\def')).toBe('\\abc\\def'); + expect((_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator('\\abc\\def\\')).toBe('\\abc\\def'); + expect(() => (_nuclideUri || _load_nuclideUri()).default.trimTrailingSeparator(archiveSuffixUri)).toThrow(); }); it('isAbsolute', () => { - expect(nuclideUri.isAbsolute('/abc')).toBe(true); - expect(nuclideUri.isAbsolute('/abc/def')).toBe(true); - expect(nuclideUri.isAbsolute('nuclide://host/')).toBe(true); - expect(nuclideUri.isAbsolute('nuclide://host/abc')).toBe(true); - expect(nuclideUri.isAbsolute('nuclide://host/abc/def')).toBe(true); - - expect(nuclideUri.isAbsolute('C:\\abc')).toBe(true); - expect(nuclideUri.isAbsolute('C:\\abc\\def')).toBe(true); - expect(nuclideUri.isAbsolute('\\abc')).toBe(true); - expect(nuclideUri.isAbsolute('\\abc\\def')).toBe(true); - - expect(nuclideUri.isAbsolute('abc')).toBe(false); - expect(nuclideUri.isAbsolute('abc/def')).toBe(false); - - expect(nuclideUri.isAbsolute('abc\\def')).toBe(false); - expect(() => nuclideUri.isAbsolute(archiveSuffixUri)).toThrow(); + expect((_nuclideUri || _load_nuclideUri()).default.isAbsolute('/abc')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isAbsolute('/abc/def')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isAbsolute('nuclide://host/')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isAbsolute('nuclide://host/abc')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isAbsolute('nuclide://host/abc/def')).toBe(true); + + expect((_nuclideUri || _load_nuclideUri()).default.isAbsolute('C:\\abc')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isAbsolute('C:\\abc\\def')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isAbsolute('\\abc')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isAbsolute('\\abc\\def')).toBe(true); + + expect((_nuclideUri || _load_nuclideUri()).default.isAbsolute('abc')).toBe(false); + expect((_nuclideUri || _load_nuclideUri()).default.isAbsolute('abc/def')).toBe(false); + + expect((_nuclideUri || _load_nuclideUri()).default.isAbsolute('abc\\def')).toBe(false); + expect(() => (_nuclideUri || _load_nuclideUri()).default.isAbsolute(archiveSuffixUri)).toThrow(); }); it('resolve', () => { - expect(nuclideUri.resolve('/abc')).toBe('/abc'); - expect(nuclideUri.resolve('/abc', '..')).toBe('/'); - expect(nuclideUri.resolve('/abc', '..', '..')).toBe('/'); - expect(nuclideUri.resolve('/abc', '../..')).toBe('/'); - - expect(nuclideUri.resolve('/abc/def')).toBe('/abc/def'); - expect(nuclideUri.resolve('/abc/def', 'ghi')).toBe('/abc/def/ghi'); - expect(nuclideUri.resolve('/abc/def', '..', 'ghi')).toBe('/abc/ghi'); - expect(nuclideUri.resolve('/abc/def', '../ghi')).toBe('/abc/ghi'); - expect(nuclideUri.resolve('/abc/def', '/ghi')).toBe('/ghi'); - - expect(nuclideUri.resolve('/z.zip!abc')).toBe('/z.zip!abc'); - expect(nuclideUri.resolve('/z.zip!abc', '..')).toBe('/z.zip'); - expect(nuclideUri.resolve('/z.zip!abc', '..', '..')).toBe('/'); - expect(nuclideUri.resolve('/z.zip!abc', '../..')).toBe('/'); - - expect(nuclideUri.resolve('/z.zip!abc', 'def')).toBe('/z.zip!abc/def'); - expect(nuclideUri.resolve('/z.zip!abc', '..', 'def')).toBe('/z.zip!def'); - expect(nuclideUri.resolve('/z.zip!abc', '../def')).toBe('/z.zip!def'); - expect(nuclideUri.resolve('/z.zip!abc', '/def')).toBe('/def'); - - expect(nuclideUri.resolve('/dir/file!abc')).toBe('/dir/file!abc'); - expect(nuclideUri.resolve('/dir/file!abc', '..')).toBe('/dir'); - expect(nuclideUri.resolve('/dir/file!abc', '..', '..')).toBe('/'); - expect(nuclideUri.resolve('/dir/file!abc', '../..')).toBe('/'); - - expect(nuclideUri.resolve('/dir/file!abc', 'def')).toBe( - '/dir/file!abc/def', - ); - expect(nuclideUri.resolve('/dir/file!abc', '..', 'def')).toBe('/dir/def'); - expect(nuclideUri.resolve('/dir/file!abc', '../def')).toBe('/dir/def'); - expect(nuclideUri.resolve('/dir/file!abc', '/def')).toBe('/def'); - - expect(nuclideUri.resolve('nuclide://host/')).toBe('nuclide://host/'); - expect(nuclideUri.resolve('nuclide://host/', '..')).toBe('nuclide://host/'); - expect(nuclideUri.resolve('nuclide://host/abc')).toBe('nuclide://host/abc'); - expect(nuclideUri.resolve('nuclide://host/abc', '..')).toBe( - 'nuclide://host/', - ); - expect(nuclideUri.resolve('nuclide://host/abc', '..', '..')).toBe( - 'nuclide://host/', - ); - expect(nuclideUri.resolve('nuclide://host/abc', '../..')).toBe( - 'nuclide://host/', - ); - expect(nuclideUri.resolve('nuclide://host/abc/def', 'ghi')).toBe( - 'nuclide://host/abc/def/ghi', - ); - expect(nuclideUri.resolve('nuclide://host/abc/def', '../ghi')).toBe( - 'nuclide://host/abc/ghi', - ); - expect(nuclideUri.resolve('nuclide://host/abc/def', '..', 'ghi')).toBe( - 'nuclide://host/abc/ghi', - ); - expect(nuclideUri.resolve('nuclide://host/abc/def', '/ghi')).toBe( - 'nuclide://host/ghi', - ); - - expect(nuclideUri.resolve('C:\\abc')).toBe('C:\\abc'); - expect(nuclideUri.resolve('C:\\abc', '..')).toBe('C:\\'); - expect(nuclideUri.resolve('C:\\abc', '..', '..')).toBe('C:\\'); - expect(nuclideUri.resolve('C:\\abc', '..\\..')).toBe('C:\\'); - expect(nuclideUri.resolve('C:\\abc', 'def')).toBe('C:\\abc\\def'); - expect(nuclideUri.resolve('C:\\abc', '..\\def')).toBe('C:\\def'); - expect(nuclideUri.resolve('C:\\abc', '..', 'def')).toBe('C:\\def'); - - expect(nuclideUri.resolve('\\abc', 'def')).toBe('\\abc\\def'); - expect(nuclideUri.resolve('\\abc', '..\\def')).toBe('\\def'); - expect(nuclideUri.resolve('\\abc', '..', 'def')).toBe('\\def'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/abc')).toBe('/abc'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/abc', '..')).toBe('/'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/abc', '..', '..')).toBe('/'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/abc', '../..')).toBe('/'); + + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/abc/def')).toBe('/abc/def'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/abc/def', 'ghi')).toBe('/abc/def/ghi'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/abc/def', '..', 'ghi')).toBe('/abc/ghi'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/abc/def', '../ghi')).toBe('/abc/ghi'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/abc/def', '/ghi')).toBe('/ghi'); + + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/z.zip!abc')).toBe('/z.zip!abc'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/z.zip!abc', '..')).toBe('/z.zip'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/z.zip!abc', '..', '..')).toBe('/'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/z.zip!abc', '../..')).toBe('/'); + + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/z.zip!abc', 'def')).toBe('/z.zip!abc/def'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/z.zip!abc', '..', 'def')).toBe('/z.zip!def'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/z.zip!abc', '../def')).toBe('/z.zip!def'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/z.zip!abc', '/def')).toBe('/def'); + + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/dir/file!abc')).toBe('/dir/file!abc'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/dir/file!abc', '..')).toBe('/dir'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/dir/file!abc', '..', '..')).toBe('/'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/dir/file!abc', '../..')).toBe('/'); + + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/dir/file!abc', 'def')).toBe( + '/dir/file!abc/def'); + + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/dir/file!abc', '..', 'def')).toBe('/dir/def'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/dir/file!abc', '../def')).toBe('/dir/def'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('/dir/file!abc', '/def')).toBe('/def'); + + expect((_nuclideUri || _load_nuclideUri()).default.resolve('nuclide://host/')).toBe('nuclide://host/'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('nuclide://host/', '..')).toBe('nuclide://host/'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('nuclide://host/abc')).toBe('nuclide://host/abc'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('nuclide://host/abc', '..')).toBe( + 'nuclide://host/'); + + expect((_nuclideUri || _load_nuclideUri()).default.resolve('nuclide://host/abc', '..', '..')).toBe( + 'nuclide://host/'); + + expect((_nuclideUri || _load_nuclideUri()).default.resolve('nuclide://host/abc', '../..')).toBe( + 'nuclide://host/'); + + expect((_nuclideUri || _load_nuclideUri()).default.resolve('nuclide://host/abc/def', 'ghi')).toBe( + 'nuclide://host/abc/def/ghi'); + + expect((_nuclideUri || _load_nuclideUri()).default.resolve('nuclide://host/abc/def', '../ghi')).toBe( + 'nuclide://host/abc/ghi'); + + expect((_nuclideUri || _load_nuclideUri()).default.resolve('nuclide://host/abc/def', '..', 'ghi')).toBe( + 'nuclide://host/abc/ghi'); + + expect((_nuclideUri || _load_nuclideUri()).default.resolve('nuclide://host/abc/def', '/ghi')).toBe( + 'nuclide://host/ghi'); + + + expect((_nuclideUri || _load_nuclideUri()).default.resolve('C:\\abc')).toBe('C:\\abc'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('C:\\abc', '..')).toBe('C:\\'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('C:\\abc', '..', '..')).toBe('C:\\'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('C:\\abc', '..\\..')).toBe('C:\\'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('C:\\abc', 'def')).toBe('C:\\abc\\def'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('C:\\abc', '..\\def')).toBe('C:\\def'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('C:\\abc', '..', 'def')).toBe('C:\\def'); + + expect((_nuclideUri || _load_nuclideUri()).default.resolve('\\abc', 'def')).toBe('\\abc\\def'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('\\abc', '..\\def')).toBe('\\def'); + expect((_nuclideUri || _load_nuclideUri()).default.resolve('\\abc', '..', 'def')).toBe('\\def'); }); describe('expandHomeDir()', () => { it('expands ~ to HOME', () => { - expect(nuclideUri.expandHomeDir('~')).toBe(process.env.HOME); + expect((_nuclideUri || _load_nuclideUri()).default.expandHomeDir('~')).toBe(process.env.HOME); }); it('expands ~/ to HOME', () => { const HOME = process.env.HOME; expect(HOME).not.toBeNull(); - expect(nuclideUri.expandHomeDir('~/abc')).toBe( - path.posix.join(HOME, 'abc'), - ); + expect((_nuclideUri || _load_nuclideUri()).default.expandHomeDir('~/abc')).toBe( + _path.default.posix.join(HOME, 'abc')); + }); it('keeps ~def to ~def', () => { - expect(nuclideUri.expandHomeDir('~def')).toBe('~def'); + expect((_nuclideUri || _load_nuclideUri()).default.expandHomeDir('~def')).toBe('~def'); }); it('throws on illegal URIs', () => { - expect(() => nuclideUri.expandHomeDir(archiveSuffixUri)).toThrow(); + expect(() => (_nuclideUri || _load_nuclideUri()).default.expandHomeDir(archiveSuffixUri)).toThrow(); }); }); it('detects Windows and Posix paths properly', () => { - expect(__TEST__._pathModuleFor('/')).toEqual(path.posix); - expect(__TEST__._pathModuleFor('/abc')).toEqual(path.posix); - expect(__TEST__._pathModuleFor('/abc/def')).toEqual(path.posix); - expect(__TEST__._pathModuleFor('/abc.txt')).toEqual(path.posix); - expect(__TEST__._pathModuleFor('nuclide://host')).toEqual(path.posix); - expect(__TEST__._pathModuleFor('nuclide://host/')).toEqual(path.posix); - expect(__TEST__._pathModuleFor('nuclide://host/abc')).toEqual(path.posix); - expect(__TEST__._pathModuleFor('nuclide://host/abc/def')).toEqual( - path.posix, - ); - expect(__TEST__._pathModuleFor('nuclide://host/abc/def.txt')).toEqual( - path.posix, - ); - expect(__TEST__._pathModuleFor('C:\\')).toEqual(path.win32); - expect(__TEST__._pathModuleFor('C:\\abc')).toEqual(path.win32); - expect(__TEST__._pathModuleFor('C:\\abc\\def')).toEqual(path.win32); - expect(__TEST__._pathModuleFor('C:\\abc\\def.txt')).toEqual(path.win32); - expect(__TEST__._pathModuleFor('D:\\abc\\aaa bbb')).toEqual(path.win32); - expect(__TEST__._pathModuleFor('\\abc\\def')).toEqual(path.win32); + expect((_nuclideUri2 || _load_nuclideUri2()).__TEST__._pathModuleFor('/')).toEqual(_path.default.posix); + expect((_nuclideUri2 || _load_nuclideUri2()).__TEST__._pathModuleFor('/abc')).toEqual(_path.default.posix); + expect((_nuclideUri2 || _load_nuclideUri2()).__TEST__._pathModuleFor('/abc/def')).toEqual(_path.default.posix); + expect((_nuclideUri2 || _load_nuclideUri2()).__TEST__._pathModuleFor('/abc.txt')).toEqual(_path.default.posix); + expect((_nuclideUri2 || _load_nuclideUri2()).__TEST__._pathModuleFor('nuclide://host')).toEqual(_path.default.posix); + expect((_nuclideUri2 || _load_nuclideUri2()).__TEST__._pathModuleFor('nuclide://host/')).toEqual(_path.default.posix); + expect((_nuclideUri2 || _load_nuclideUri2()).__TEST__._pathModuleFor('nuclide://host/abc')).toEqual(_path.default.posix); + expect((_nuclideUri2 || _load_nuclideUri2()).__TEST__._pathModuleFor('nuclide://host/abc/def')).toEqual( + _path.default.posix); + + expect((_nuclideUri2 || _load_nuclideUri2()).__TEST__._pathModuleFor('nuclide://host/abc/def.txt')).toEqual( + _path.default.posix); + + expect((_nuclideUri2 || _load_nuclideUri2()).__TEST__._pathModuleFor('C:\\')).toEqual(_path.default.win32); + expect((_nuclideUri2 || _load_nuclideUri2()).__TEST__._pathModuleFor('C:\\abc')).toEqual(_path.default.win32); + expect((_nuclideUri2 || _load_nuclideUri2()).__TEST__._pathModuleFor('C:\\abc\\def')).toEqual(_path.default.win32); + expect((_nuclideUri2 || _load_nuclideUri2()).__TEST__._pathModuleFor('C:\\abc\\def.txt')).toEqual(_path.default.win32); + expect((_nuclideUri2 || _load_nuclideUri2()).__TEST__._pathModuleFor('D:\\abc\\aaa bbb')).toEqual(_path.default.win32); + expect((_nuclideUri2 || _load_nuclideUri2()).__TEST__._pathModuleFor('\\abc\\def')).toEqual(_path.default.win32); // Default to Posix - expect(__TEST__._pathModuleFor('abcdef')).toEqual(path.posix); + expect((_nuclideUri2 || _load_nuclideUri2()).__TEST__._pathModuleFor('abcdef')).toEqual(_path.default.posix); }); it('properly converts file URIs to local paths', () => { - expect(nuclideUri.uriToNuclideUri('\\abc\\def')).toEqual(null); - expect(nuclideUri.uriToNuclideUri('file://somehost/file/path')).toEqual( - '/file/path', - ); + expect((_nuclideUri || _load_nuclideUri()).default.uriToNuclideUri('\\abc\\def')).toEqual(null); + expect((_nuclideUri || _load_nuclideUri()).default.uriToNuclideUri('file://somehost/file/path')).toEqual( + '/file/path'); + expect( - nuclideUri.uriToNuclideUri( - 'file:///foo/bar/buck-out/flavor%231%232%233%2Cabc', - ), - ).toEqual('/foo/bar/buck-out/flavor#1#2#3,abc'); + (_nuclideUri || _load_nuclideUri()).default.uriToNuclideUri( + 'file:///foo/bar/buck-out/flavor%231%232%233%2Cabc')). + + toEqual('/foo/bar/buck-out/flavor#1#2#3,abc'); expect( - nuclideUri.uriToNuclideUri('file:///file/path/file_%25.ext'), - ).toEqual('/file/path/file_%.ext'); - expect(nuclideUri.uriToNuclideUri('file://C:\\some\\file\\path')).toEqual( - 'C:\\some\\file\\path', - ); + (_nuclideUri || _load_nuclideUri()).default.uriToNuclideUri('file:///file/path/file_%25.ext')). + toEqual('/file/path/file_%.ext'); + expect((_nuclideUri || _load_nuclideUri()).default.uriToNuclideUri('file://C:\\some\\file\\path')).toEqual( + 'C:\\some\\file\\path'); + }); it('properly converts local paths to file URIs', () => { - expect(nuclideUri.nuclideUriToUri('/foo/bar/file.ext')).toEqual( - 'file:///foo/bar/file.ext', - ); + expect((_nuclideUri || _load_nuclideUri()).default.nuclideUriToUri('/foo/bar/file.ext')).toEqual( + 'file:///foo/bar/file.ext'); + expect( - nuclideUri.nuclideUriToUri('/foo/bar/buck-out/flavor#1#2#3,abc'), - ).toEqual('file:///foo/bar/buck-out/flavor%231%232%233%2Cabc'); - expect(nuclideUri.nuclideUriToUri('/file/path/file_%.ext')).toEqual( - 'file:///file/path/file_%25.ext', - ); + (_nuclideUri || _load_nuclideUri()).default.nuclideUriToUri('/foo/bar/buck-out/flavor#1#2#3,abc')). + toEqual('file:///foo/bar/buck-out/flavor%231%232%233%2Cabc'); + expect((_nuclideUri || _load_nuclideUri()).default.nuclideUriToUri('/file/path/file_%.ext')).toEqual( + 'file:///file/path/file_%25.ext'); + }); it('properly handles backslash-containing remote URIs', () => { - expect(nuclideUri.getPath('nuclide://host/aaa\\bbb.txt')).toBe( - '/aaa\\bbb.txt', - ); - expect(nuclideUri.getPath('nuclide://host/dir/aaa\\bbb.txt')).toBe( - '/dir/aaa\\bbb.txt', - ); - expect(nuclideUri.getPath('nuclide://host/one\\two\\file.txt')).toBe( - '/one\\two\\file.txt', - ); + expect((_nuclideUri || _load_nuclideUri()).default.getPath('nuclide://host/aaa\\bbb.txt')).toBe( + '/aaa\\bbb.txt'); + + expect((_nuclideUri || _load_nuclideUri()).default.getPath('nuclide://host/dir/aaa\\bbb.txt')).toBe( + '/dir/aaa\\bbb.txt'); + + expect((_nuclideUri || _load_nuclideUri()).default.getPath('nuclide://host/one\\two\\file.txt')).toBe( + '/one\\two\\file.txt'); + }); it('correctly distinguishes paths that refer to files in an archive', () => { - expect(nuclideUri.isInArchive('abc')).toBe(false); - expect(nuclideUri.isInArchive('/abc')).toBe(false); - expect(nuclideUri.isInArchive('nuclide://host/abc')).toBe(false); - expect(nuclideUri.isInArchive('abc.zip')).toBe(false); - expect(nuclideUri.isInArchive('abc.jar')).toBe(false); - expect(nuclideUri.isInArchive('abc.zip!def')).toBe(true); - expect(nuclideUri.isInArchive('abc.jar!def')).toBe(true); - expect(nuclideUri.isInArchive('/abc.zip!def')).toBe(true); - expect(nuclideUri.isInArchive('/abc.jar!def')).toBe(true); - expect(nuclideUri.isInArchive('C:\\abc.zip!def')).toBe(true); - expect(nuclideUri.isInArchive('C:\\abc.jar!def')).toBe(true); - expect(nuclideUri.isInArchive('nuclide://host/abc.zip!def')).toBe(true); - expect(nuclideUri.isInArchive('nuclide://host/abc.jar!def')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isInArchive('abc')).toBe(false); + expect((_nuclideUri || _load_nuclideUri()).default.isInArchive('/abc')).toBe(false); + expect((_nuclideUri || _load_nuclideUri()).default.isInArchive('nuclide://host/abc')).toBe(false); + expect((_nuclideUri || _load_nuclideUri()).default.isInArchive('abc.zip')).toBe(false); + expect((_nuclideUri || _load_nuclideUri()).default.isInArchive('abc.jar')).toBe(false); + expect((_nuclideUri || _load_nuclideUri()).default.isInArchive('abc.zip!def')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isInArchive('abc.jar!def')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isInArchive('/abc.zip!def')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isInArchive('/abc.jar!def')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isInArchive('C:\\abc.zip!def')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isInArchive('C:\\abc.jar!def')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isInArchive('nuclide://host/abc.zip!def')).toBe(true); + expect((_nuclideUri || _load_nuclideUri()).default.isInArchive('nuclide://host/abc.jar!def')).toBe(true); }); it('reports first ancestor outside archive', () => { - expect(nuclideUri.ancestorOutsideArchive('abc')).toBe('abc'); - expect(nuclideUri.ancestorOutsideArchive('/abc')).toBe('/abc'); - expect(nuclideUri.ancestorOutsideArchive('nuclide://host/abc')).toBe( - 'nuclide://host/abc', - ); - expect(nuclideUri.ancestorOutsideArchive('abc.zip')).toBe('abc.zip'); - expect(nuclideUri.ancestorOutsideArchive('abc.jar')).toBe('abc.jar'); - expect(nuclideUri.ancestorOutsideArchive('abc.zip!def')).toBe('abc.zip'); - expect(nuclideUri.ancestorOutsideArchive('abc.jar!def')).toBe('abc.jar'); - expect(nuclideUri.ancestorOutsideArchive('/abc.zip!def')).toBe('/abc.zip'); - expect(nuclideUri.ancestorOutsideArchive('/abc.jar!def')).toBe('/abc.jar'); - expect(nuclideUri.ancestorOutsideArchive('C:\\abc.zip!def')).toBe( - 'C:\\abc.zip', - ); - expect(nuclideUri.ancestorOutsideArchive('C:\\abc.jar!def')).toBe( - 'C:\\abc.jar', - ); + expect((_nuclideUri || _load_nuclideUri()).default.ancestorOutsideArchive('abc')).toBe('abc'); + expect((_nuclideUri || _load_nuclideUri()).default.ancestorOutsideArchive('/abc')).toBe('/abc'); + expect((_nuclideUri || _load_nuclideUri()).default.ancestorOutsideArchive('nuclide://host/abc')).toBe( + 'nuclide://host/abc'); + + expect((_nuclideUri || _load_nuclideUri()).default.ancestorOutsideArchive('abc.zip')).toBe('abc.zip'); + expect((_nuclideUri || _load_nuclideUri()).default.ancestorOutsideArchive('abc.jar')).toBe('abc.jar'); + expect((_nuclideUri || _load_nuclideUri()).default.ancestorOutsideArchive('abc.zip!def')).toBe('abc.zip'); + expect((_nuclideUri || _load_nuclideUri()).default.ancestorOutsideArchive('abc.jar!def')).toBe('abc.jar'); + expect((_nuclideUri || _load_nuclideUri()).default.ancestorOutsideArchive('/abc.zip!def')).toBe('/abc.zip'); + expect((_nuclideUri || _load_nuclideUri()).default.ancestorOutsideArchive('/abc.jar!def')).toBe('/abc.jar'); + expect((_nuclideUri || _load_nuclideUri()).default.ancestorOutsideArchive('C:\\abc.zip!def')).toBe( + 'C:\\abc.zip'); + + expect((_nuclideUri || _load_nuclideUri()).default.ancestorOutsideArchive('C:\\abc.jar!def')).toBe( + 'C:\\abc.jar'); + expect( - nuclideUri.ancestorOutsideArchive('nuclide://host/abc.zip!def'), - ).toBe('nuclide://host/abc.zip'); + (_nuclideUri || _load_nuclideUri()).default.ancestorOutsideArchive('nuclide://host/abc.zip!def')). + toBe('nuclide://host/abc.zip'); expect( - nuclideUri.ancestorOutsideArchive('nuclide://host/abc.jar!def'), - ).toBe('nuclide://host/abc.jar'); + (_nuclideUri || _load_nuclideUri()).default.ancestorOutsideArchive('nuclide://host/abc.jar!def')). + toBe('nuclide://host/abc.jar'); }); -}); +}); // eslint-disable-next-line rulesdir/prefer-nuclide-uri \ No newline at end of file diff --git a/modules/nuclide-commons/spec/observable-spec.js b/modules/nuclide-commons/spec/observable-spec.js index 04219984..430174c3 100644 --- a/modules/nuclide-commons/spec/observable-spec.js +++ b/modules/nuclide-commons/spec/observable-spec.js @@ -1,83 +1,83 @@ -/** - * 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 - * @format - */ - -import type {AbortSignal} from '../AbortController'; - -import { - bufferUntil, - cacheWhileSubscribed, - completingSwitchMap, - concatLatest, - diffSets, - fastDebounce, - fromAbortablePromise, - macrotask, - microtask, - nextAnimationFrame, - poll, - reconcileSetDiffs, - SingletonExecutor, - splitStream, - takeUntilAbort, - takeWhileInclusive, - throttle, - toAbortablePromise, - toggle, -} from '../observable'; -import nullthrows from 'nullthrows'; -import AbortController from '../AbortController'; -import UniversalDisposable from '../UniversalDisposable'; -import {Observable, Subject} from 'rxjs'; - -const setsAreEqual = (a, b) => - a.size === b.size && Array.from(a).every(b.has.bind(b)); -const diffsAreEqual = (a, b) => - setsAreEqual(a.added, b.added) && setsAreEqual(a.removed, b.removed); -const createDisposable = () => { - const disposable = new UniversalDisposable(); - spyOn(disposable, 'dispose'); - return disposable; -}; +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _observable; + + + + + + + + + + + + + +function _load_observable() {return _observable = require('../observable');}var _nullthrows; + + + + + + + + + + + + + + + + + + + + +function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));}var _AbortController; +function _load_AbortController() {return _AbortController = _interopRequireDefault(require('../AbortController'));}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('../UniversalDisposable'));} +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */const setsAreEqual = (a, b) => a.size === b.size && Array.from(a).every(b.has.bind(b));const diffsAreEqual = (a, b) => setsAreEqual(a.added, b.added) && setsAreEqual(a.removed, b.removed);const createDisposable = () => {const disposable = new (_UniversalDisposable || _load_UniversalDisposable()).default();spyOn(disposable, 'dispose');return disposable;}; describe('nuclide-commons/observable', () => { describe('splitStream', () => { it('splits streams', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { const input = ['foo\nbar', '\n', '\nba', 'z', '\nblar']; - const output = await splitStream(Observable.from(input)) - .toArray() - .toPromise(); + const output = yield (0, (_observable || _load_observable()).splitStream)(_rxjsBundlesRxMinJs.Observable.from(input)). + toArray(). + toPromise(); expect(output).toEqual(['foo\n', 'bar\n', '\n', 'baz\n', 'blar']); - }); + })); }); it('splits streams without the newline', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { const input = ['foo\nbar', '\n', '\nba', 'z', '\nblar']; - const output = await splitStream(Observable.from(input), false) - .toArray() - .toPromise(); + const output = yield (0, (_observable || _load_observable()).splitStream)(_rxjsBundlesRxMinJs.Observable.from(input), false). + toArray(). + toPromise(); expect(output).toEqual(['foo', 'bar', '', 'baz', 'blar']); - }); + })); }); }); describe('takeWhileInclusive', () => { it('completes the stream when something matches the predicate', () => { - const source = new Subject(); - const result = source.let(takeWhileInclusive(x => x !== 2)); - const next: (n: number) => mixed = jasmine.createSpy(); - const complete: () => mixed = jasmine.createSpy(); - result.subscribe({next, complete}); + const source = new _rxjsBundlesRxMinJs.Subject(); + const result = source.let((0, (_observable || _load_observable()).takeWhileInclusive)(x => x !== 2)); + const next = jasmine.createSpy(); + const complete = jasmine.createSpy(); + result.subscribe({ next, complete }); source.next(1); source.next(2); source.next(3); @@ -87,15 +87,15 @@ describe('nuclide-commons/observable', () => { }); describe('cacheWhileSubscribed', () => { - let input: Subject = (null: any); - let output: Observable = (null: any); + let input = null; + let output = null; - function subscribeArray(arr: Array): rxjs$ISubscription { + function subscribeArray(arr) { return output.subscribe(x => arr.push(x)); } beforeEach(() => { - input = new Subject(); - output = cacheWhileSubscribed(input); + input = new _rxjsBundlesRxMinJs.Subject(); + output = (0, (_observable || _load_observable()).cacheWhileSubscribed)(input); }); it('should provide cached values to late subscribers', () => { @@ -136,217 +136,217 @@ describe('nuclide-commons/observable', () => { describe('diffSets', () => { it('emits a diff for the first item', () => { - waitsForPromise(async () => { - const source = new Subject(); - const diffsPromise = source - .let(diffSets()) - .toArray() - .toPromise(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const source = new _rxjsBundlesRxMinJs.Subject(); + const diffsPromise = source. + let((0, (_observable || _load_observable()).diffSets)()). + toArray(). + toPromise(); source.next(new Set([1, 2, 3])); source.complete(); - const diffs = await diffsPromise; + const diffs = yield diffsPromise; expect(diffs.length).toBe(1); expect( - diffsAreEqual(diffs[0], { - added: new Set([1, 2, 3]), - removed: new Set(), - }), - ).toBe(true); - }); + diffsAreEqual(diffs[0], { + added: new Set([1, 2, 3]), + removed: new Set() })). + + toBe(true); + })); }); it('correctly identifies removed items', () => { - waitsForPromise(async () => { - const source = new Subject(); - const diffsPromise = source - .let(diffSets()) - .toArray() - .toPromise(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const source = new _rxjsBundlesRxMinJs.Subject(); + const diffsPromise = source. + let((0, (_observable || _load_observable()).diffSets)()). + toArray(). + toPromise(); source.next(new Set([1, 2, 3])); source.next(new Set([1, 2])); source.complete(); - const diffs = await diffsPromise; + const diffs = yield diffsPromise; expect(setsAreEqual(diffs[1].removed, new Set([3]))).toBe(true); - }); + })); }); it('correctly identifies removed items when a hash function is used', () => { - waitsForPromise(async () => { - const source = new Subject(); - const diffsPromise = source - .let(diffSets(x => x.key)) - .toArray() - .toPromise(); - const firstItems = [{key: 1}, {key: 2}, {key: 3}]; - const secondItems = [{key: 1}, {key: 2}]; + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const source = new _rxjsBundlesRxMinJs.Subject(); + const diffsPromise = source. + let((0, (_observable || _load_observable()).diffSets)(function (x) {return x.key;})). + toArray(). + toPromise(); + const firstItems = [{ key: 1 }, { key: 2 }, { key: 3 }]; + const secondItems = [{ key: 1 }, { key: 2 }]; source.next(new Set(firstItems)); source.next(new Set(secondItems)); source.complete(); - const diffs = await diffsPromise; + const diffs = yield diffsPromise; expect(setsAreEqual(diffs[1].removed, new Set([firstItems[2]]))).toBe( - true, - ); - }); + true); + + })); }); it('correctly identifies added items', () => { - waitsForPromise(async () => { - const source = new Subject(); - const diffsPromise = source - .let(diffSets()) - .toArray() - .toPromise(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const source = new _rxjsBundlesRxMinJs.Subject(); + const diffsPromise = source. + let((0, (_observable || _load_observable()).diffSets)()). + toArray(). + toPromise(); source.next(new Set([1, 2])); source.next(new Set([1, 2, 3])); source.complete(); - const diffs = await diffsPromise; + const diffs = yield diffsPromise; expect(setsAreEqual(diffs[1].added, new Set([3]))).toBe(true); - }); + })); }); it('correctly identifies added items when a hash function is used', () => { - waitsForPromise(async () => { - const source = new Subject(); - const diffsPromise = source - .let(diffSets(x => x.key)) - .toArray() - .toPromise(); - const firstItems = [{key: 1}, {key: 2}]; - const secondItems = [{key: 1}, {key: 2}, {key: 3}]; + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const source = new _rxjsBundlesRxMinJs.Subject(); + const diffsPromise = source. + let((0, (_observable || _load_observable()).diffSets)(function (x) {return x.key;})). + toArray(). + toPromise(); + const firstItems = [{ key: 1 }, { key: 2 }]; + const secondItems = [{ key: 1 }, { key: 2 }, { key: 3 }]; source.next(new Set(firstItems)); source.next(new Set(secondItems)); source.complete(); - const diffs = await diffsPromise; + const diffs = yield diffsPromise; expect(setsAreEqual(diffs[1].added, new Set([secondItems[2]]))).toBe( - true, - ); - }); + true); + + })); }); it("doesn't emit a diff when nothing changes", () => { - waitsForPromise(async () => { - const source = new Subject(); - const diffsPromise = source - .let(diffSets()) - .toArray() - .toPromise(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const source = new _rxjsBundlesRxMinJs.Subject(); + const diffsPromise = source. + let((0, (_observable || _load_observable()).diffSets)()). + toArray(). + toPromise(); source.next(new Set([1, 2, 3])); source.next(new Set([1, 2, 3])); source.complete(); - const diffs = await diffsPromise; + const diffs = yield diffsPromise; // Make sure we only get one diff (from the implicit initial empty set). expect(diffs.length).toBe(1); - }); + })); }); it("doesn't emit a diff when nothing changes and a hash function is used", () => { - waitsForPromise(async () => { - const source = new Subject(); - const diffsPromise = source - .let(diffSets(x => x.key)) - .toArray() - .toPromise(); - const firstItems = [{key: 1}, {key: 2}, {key: 3}]; - const secondItems = [{key: 1}, {key: 2}, {key: 3}]; + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const source = new _rxjsBundlesRxMinJs.Subject(); + const diffsPromise = source. + let((0, (_observable || _load_observable()).diffSets)(function (x) {return x.key;})). + toArray(). + toPromise(); + const firstItems = [{ key: 1 }, { key: 2 }, { key: 3 }]; + const secondItems = [{ key: 1 }, { key: 2 }, { key: 3 }]; source.next(new Set(firstItems)); source.next(new Set(secondItems)); source.complete(); - const diffs = await diffsPromise; + const diffs = yield diffsPromise; // Make sure we only get one diff (from the implicit initial empty set). expect(diffs.length).toBe(1); - }); + })); }); }); describe('reconcileSetDiffs', () => { it("calls the add action for each item that's added", () => { - const diffs = new Subject(); - const addAction = jasmine - .createSpy() - .andReturn(new UniversalDisposable()); - reconcileSetDiffs(diffs, addAction); + const diffs = new _rxjsBundlesRxMinJs.Subject(); + const addAction = jasmine. + createSpy(). + andReturn(new (_UniversalDisposable || _load_UniversalDisposable()).default()); + (0, (_observable || _load_observable()).reconcileSetDiffs)(diffs, addAction); diffs.next({ added: new Set(['a', 'b']), - removed: new Set(), - }); + removed: new Set() }); + expect(addAction.calls.map(call => call.args[0])).toEqual(['a', 'b']); }); it("disposes for each item that's removed", () => { - const diffs = new Subject(); + const diffs = new _rxjsBundlesRxMinJs.Subject(); const disposables = { a: createDisposable(), - b: createDisposable(), - }; + b: createDisposable() }; + const addAction = item => disposables[item]; - reconcileSetDiffs(diffs, addAction); + (0, (_observable || _load_observable()).reconcileSetDiffs)(diffs, addAction); diffs.next({ added: new Set(['a', 'b']), - removed: new Set(), - }); + removed: new Set() }); + diffs.next({ added: new Set(), - removed: new Set(['a', 'b']), - }); + removed: new Set(['a', 'b']) }); + expect(disposables.a.dispose).toHaveBeenCalled(); expect(disposables.b.dispose).toHaveBeenCalled(); }); it('disposes for all items when disposed', () => { - const diffs = new Subject(); + const diffs = new _rxjsBundlesRxMinJs.Subject(); const disposables = { a: createDisposable(), - b: createDisposable(), - }; + b: createDisposable() }; + const addAction = item => disposables[item]; - const reconciliationDisposable = reconcileSetDiffs(diffs, addAction); + const reconciliationDisposable = (0, (_observable || _load_observable()).reconcileSetDiffs)(diffs, addAction); diffs.next({ added: new Set(['a', 'b']), - removed: new Set(), - }); + removed: new Set() }); + reconciliationDisposable.dispose(); expect(disposables.a.dispose).toHaveBeenCalled(); expect(disposables.b.dispose).toHaveBeenCalled(); }); it("disposes for each item that's removed when a hash function is used", () => { - const diffs = new Subject(); + const diffs = new _rxjsBundlesRxMinJs.Subject(); const disposables = { a: createDisposable(), - b: createDisposable(), - }; + b: createDisposable() }; + const addAction = item => disposables[item.key]; - reconcileSetDiffs(diffs, addAction, x => x.key); + (0, (_observable || _load_observable()).reconcileSetDiffs)(diffs, addAction, x => x.key); diffs.next({ - added: new Set([{key: 'a'}, {key: 'b'}]), - removed: new Set(), - }); + added: new Set([{ key: 'a' }, { key: 'b' }]), + removed: new Set() }); + diffs.next({ added: new Set(), - removed: new Set([{key: 'a'}, {key: 'b'}]), - }); + removed: new Set([{ key: 'a' }, { key: 'b' }]) }); + expect(disposables.a.dispose).toHaveBeenCalled(); expect(disposables.b.dispose).toHaveBeenCalled(); }); }); describe('toggle', () => { - let toggler: Subject = (null: any); - let source: Observable = (null: any); - let output: Observable = (null: any); - let outputArray: Array = (null: any); + let toggler = null; + let source = null; + let output = null; + let outputArray = null; beforeEach(() => { - toggler = new Subject(); + toggler = new _rxjsBundlesRxMinJs.Subject(); // Deferred so individual 'it' blocks can set the source on the fly. - output = Observable.defer(() => source).let(toggle(toggler)); + output = _rxjsBundlesRxMinJs.Observable.defer(() => source).let((0, (_observable || _load_observable()).toggle)(toggler)); }); describe('with a standard source', () => { - let realSource: Subject = (null: any); + let realSource = null; beforeEach(() => { - source = realSource = new Subject(); + source = realSource = new _rxjsBundlesRxMinJs.Subject(); outputArray = []; output.subscribe(x => outputArray.push(x)); }); @@ -374,7 +374,7 @@ describe('nuclide-commons/observable', () => { // that toggling off unsubscribes and then resubscribes. describe('subscription behavior', () => { beforeEach(() => { - source = Observable.of(1, 2, 3); + source = _rxjsBundlesRxMinJs.Observable.of(1, 2, 3); outputArray = []; output.subscribe(x => outputArray.push(x)); }); @@ -402,49 +402,49 @@ describe('nuclide-commons/observable', () => { describe('concatLatest', () => { it('should work with empty input', () => { - waitsForPromise(async () => { - const output = await concatLatest() - .toArray() - .toPromise(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const output = yield (0, (_observable || _load_observable()).concatLatest)(). + toArray(). + toPromise(); expect(output).toEqual([]); - }); + })); }); it('should work with several observables', () => { - waitsForPromise(async () => { - const output = await concatLatest( - Observable.of([], [1]), - Observable.of([2]), - Observable.of([3], [3, 4]), - ) - .toArray() - .toPromise(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const output = yield (0, (_observable || _load_observable()).concatLatest)( + _rxjsBundlesRxMinJs.Observable.of([], [1]), + _rxjsBundlesRxMinJs.Observable.of([2]), + _rxjsBundlesRxMinJs.Observable.of([3], [3, 4])). + + toArray(). + toPromise(); expect(output).toEqual([[], [1], [1, 2], [1, 2, 3], [1, 2, 3, 4]]); - }); + })); }); }); describe('throttle', () => { it('emits the leading item immeditately by default', () => { - const source = Observable.of(1, 2).merge(Observable.never()); + const source = _rxjsBundlesRxMinJs.Observable.of(1, 2).merge(_rxjsBundlesRxMinJs.Observable.never()); const spy = jasmine.createSpy(); - source.let(throttle(Observable.never())).subscribe(spy); + source.let((0, (_observable || _load_observable()).throttle)(_rxjsBundlesRxMinJs.Observable.never())).subscribe(spy); expect(spy).toHaveBeenCalledWith(1); }); it("doesn't emit the leading item twice", () => { - const source = Observable.of(1).merge(Observable.never()); - const notifier = Observable.of(null); // emits immediately on subscription. + const source = _rxjsBundlesRxMinJs.Observable.of(1).merge(_rxjsBundlesRxMinJs.Observable.never()); + const notifier = _rxjsBundlesRxMinJs.Observable.of(null); // emits immediately on subscription. const spy = jasmine.createSpy(); - source.let(throttle(notifier)).subscribe(spy); + source.let((0, (_observable || _load_observable()).throttle)(notifier)).subscribe(spy); expect(spy.callCount).toBe(1); }); it('throttles', () => { - const source = new Subject(); - const notifier = new Subject(); + const source = new _rxjsBundlesRxMinJs.Subject(); + const notifier = new _rxjsBundlesRxMinJs.Subject(); const spy = jasmine.createSpy(); - source.let(throttle(notifier)).subscribe(spy); + source.let((0, (_observable || _load_observable()).throttle)(notifier)).subscribe(spy); source.next(1); spy.reset(); source.next(2); @@ -463,8 +463,8 @@ describe('nuclide-commons/observable', () => { it('subscribes to the source once per subscription', () => { const spy = jasmine.createSpy(); - const source = Observable.create(spy); - source.let(throttle(Observable.of(null))).subscribe(); + const source = _rxjsBundlesRxMinJs.Observable.create(spy); + source.let((0, (_observable || _load_observable()).throttle)(_rxjsBundlesRxMinJs.Observable.of(null))).subscribe(); expect(spy.callCount).toBe(1); }); }); @@ -485,13 +485,13 @@ describe('nuclide-commons/observable', () => { }); it('schedules next using requestAnimationFrame', () => { - const sub = nextAnimationFrame.subscribe(); + const sub = (_observable || _load_observable()).nextAnimationFrame.subscribe(); expect(window.requestAnimationFrame).toHaveBeenCalled(); sub.unsubscribe(); }); it('uses cancelAnimationFrame when unsubscribed', () => { - const sub = nextAnimationFrame.subscribe(); + const sub = (_observable || _load_observable()).nextAnimationFrame.subscribe(); expect(window.cancelAnimationFrame).not.toHaveBeenCalled(); sub.unsubscribe(); expect(window.cancelAnimationFrame).toHaveBeenCalled(); @@ -500,64 +500,64 @@ describe('nuclide-commons/observable', () => { describe('bufferUntil', () => { it('buffers based on the predicate', () => { - waitsForPromise(async () => { - const chunks = await Observable.of(1, 2, 3, 4) - .let(bufferUntil(x => x % 2 === 0)) - .toArray() - .toPromise(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const chunks = yield _rxjsBundlesRxMinJs.Observable.of(1, 2, 3, 4). + let((0, (_observable || _load_observable()).bufferUntil)(function (x) {return x % 2 === 0;})). + toArray(). + toPromise(); expect(chunks).toEqual([[1, 2], [3, 4]]); - }); + })); }); it('provides the current buffer', () => { - waitsForPromise(async () => { - const chunks = await Observable.of(1, 2, 3, 4) - .let(bufferUntil((x, buffer) => buffer.length === 2)) - .toArray() - .toPromise(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const chunks = yield _rxjsBundlesRxMinJs.Observable.of(1, 2, 3, 4). + let((0, (_observable || _load_observable()).bufferUntil)(function (x, buffer) {return buffer.length === 2;})). + toArray(). + toPromise(); expect(chunks).toEqual([[1, 2], [3, 4]]); - }); + })); }); }); describe('completingSwitchMap', () => { it('propagates completions to the inner observable', () => { - waitsForPromise(async () => { - const results = await Observable.of(1, 2) - .let( - completingSwitchMap(x => { - return Observable.concat( - Observable.of(x + 1), - Observable.never(), - ); - }), - ) - .toArray() - .toPromise(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const results = yield _rxjsBundlesRxMinJs.Observable.of(1, 2). + let( + (0, (_observable || _load_observable()).completingSwitchMap)(function (x) { + return _rxjsBundlesRxMinJs.Observable.concat( + _rxjsBundlesRxMinJs.Observable.of(x + 1), + _rxjsBundlesRxMinJs.Observable.never()); + + })). + + toArray(). + toPromise(); expect(results).toEqual([2, 3]); - }); + })); }); }); describe('fastDebounce', () => { it('debounces events', () => { - waitsForPromise(async () => { - let nextSpy: JasmineSpy; - const originalCreate = Observable.create.bind(Observable); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + let nextSpy; + const originalCreate = _rxjsBundlesRxMinJs.Observable.create.bind(_rxjsBundlesRxMinJs.Observable); // Spy on the created observer's next to ensure that we always cancel // the last debounced timer on unsubscribe. - spyOn(Observable, 'create').andCallFake(callback => { - return originalCreate(observer => { + spyOn(_rxjsBundlesRxMinJs.Observable, 'create').andCallFake(function (callback) { + return originalCreate(function (observer) { nextSpy = spyOn(observer, 'next').andCallThrough(); return callback(observer); }); }); - const subject = new Subject(); - const promise = subject - .let(fastDebounce(10)) - .toArray() - .toPromise(); + const subject = new _rxjsBundlesRxMinJs.Subject(); + const promise = subject. + let((0, (_observable || _load_observable()).fastDebounce)(10)). + toArray(). + toPromise(); subject.next(1); subject.next(2); @@ -573,45 +573,45 @@ describe('nuclide-commons/observable', () => { subject.complete(); advanceClock(20); - expect(await promise).toEqual([2, 4]); - expect(nullthrows(nextSpy).callCount).toBe(2); - }); + expect((yield promise)).toEqual([2, 4]); + expect((0, (_nullthrows || _load_nullthrows()).default)(nextSpy).callCount).toBe(2); + })); }); it('passes errors through immediately', () => { let caught = false; - Observable.throw(1) - .let(fastDebounce(10)) - .subscribe({ - error() { - caught = true; - }, - }); + _rxjsBundlesRxMinJs.Observable.throw(1). + let((0, (_observable || _load_observable()).fastDebounce)(10)). + subscribe({ + error() { + caught = true; + } }); + expect(caught).toBe(true); }); }); describe('microtask', () => { it('is cancelable', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { const spy = jasmine.createSpy(); - const sub = microtask.subscribe(spy); + const sub = (_observable || _load_observable()).microtask.subscribe(spy); let resolve; - const promise = new Promise(r => (resolve = r)); + const promise = new Promise(function (r) {return resolve = r;}); sub.unsubscribe(); - process.nextTick(() => { + process.nextTick(function () { expect(spy).not.toHaveBeenCalled(); resolve(); }); return promise; - }); + })); }); }); describe('macrotask', () => { it('is cancelable', () => { spyOn(global, 'clearImmediate').andCallThrough(); - const sub = macrotask.subscribe(() => {}); + const sub = (_observable || _load_observable()).macrotask.subscribe(() => {}); sub.unsubscribe(); expect(clearImmediate).toHaveBeenCalled(); }); @@ -620,58 +620,58 @@ describe('nuclide-commons/observable', () => { describe('fromAbortablePromise', () => { it('is able to cancel a promise after unsubscription', () => { const spy = jasmine.createSpy('onabort'); - function f(signal: AbortSignal) { + function f(signal) { expect(signal.aborted).toBe(false); signal.onabort = spy; return new Promise(resolve => {}); } - const subscription = fromAbortablePromise(f).subscribe(); + const subscription = (0, (_observable || _load_observable()).fromAbortablePromise)(f).subscribe(); subscription.unsubscribe(); expect(spy).toHaveBeenCalled(); }); it('does not trigger an abort after normal completion', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { const spy = jasmine.createSpy('onabort'); - function f(signal: AbortSignal) { + function f(signal) { signal.onabort = spy; return Promise.resolve(1); } - const result = await fromAbortablePromise(f).toPromise(); + const result = yield (0, (_observable || _load_observable()).fromAbortablePromise)(f).toPromise(); expect(result).toBe(1); expect(spy).not.toHaveBeenCalled(); - }); + })); }); }); describe('toAbortablePromise', () => { it('rejects with a DOMException on abort', () => { - waitsForPromise(async () => { - const controller = new AbortController(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const controller = new (_AbortController || _load_AbortController()).default(); const spy = jasmine.createSpy('error'); - const promise = toAbortablePromise( - Observable.never(), - controller.signal, - ).catch(spy); + const promise = (0, (_observable || _load_observable()).toAbortablePromise)( + _rxjsBundlesRxMinJs.Observable.never(), + controller.signal). + catch(spy); controller.abort(); - await promise; + yield promise; expect(spy).toHaveBeenCalled(); - const exception: any = spy.calls[0].args[0]; + const exception = spy.calls[0].args[0]; expect(exception.constructor.name).toBe('DOMException'); expect(exception.name).toBe('AbortError'); expect(exception.message).toBe('Aborted'); - }); + })); }); describe('takeUntilAbort', () => { it('completes on abort', () => { - const controller = new AbortController(); + const controller = new (_AbortController || _load_AbortController()).default(); const spy = jasmine.createSpy('completed'); - Observable.never() - .let(obs => takeUntilAbort(obs, controller.signal)) - .subscribe({complete: spy}); + _rxjsBundlesRxMinJs.Observable.never(). + let(obs => (0, (_observable || _load_observable()).takeUntilAbort)(obs, controller.signal)). + subscribe({ complete: spy }); expect(spy).not.toHaveBeenCalled(); controller.abort(); @@ -679,32 +679,32 @@ describe('nuclide-commons/observable', () => { }); it('completes when already aborted', () => { - const controller = new AbortController(); + const controller = new (_AbortController || _load_AbortController()).default(); controller.abort(); const spy = jasmine.createSpy('completed'); - Observable.never() - .let(obs => takeUntilAbort(obs, controller.signal)) - .subscribe({complete: spy}); + _rxjsBundlesRxMinJs.Observable.never(). + let(obs => (0, (_observable || _load_observable()).takeUntilAbort)(obs, controller.signal)). + subscribe({ complete: spy }); expect(spy).toHaveBeenCalled(); }); }); it('works with no signal', () => { - waitsForPromise(async () => { - const promise = toAbortablePromise(Observable.of(1)); - expect(await promise).toBe(1); - }); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const promise = (0, (_observable || _load_observable()).toAbortablePromise)(_rxjsBundlesRxMinJs.Observable.of(1)); + expect((yield promise)).toBe(1); + })); }); }); describe('SingletonExecutor', () => { it('isExecuting()', () => { - const executor = new SingletonExecutor(); + const executor = new (_observable || _load_observable()).SingletonExecutor(); expect(executor.isExecuting()).toBe(false); - const source = new Subject(); + const source = new _rxjsBundlesRxMinJs.Subject(); const result = executor.execute(source); result.catch(() => 'silence unhandled promise rejection warning'); expect(executor.isExecuting()).toBe(true); @@ -714,24 +714,24 @@ describe('nuclide-commons/observable', () => { }); it('completing task normally', () => { - waitsForPromise(async () => { - const executor = new SingletonExecutor(); - const source = new Subject(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const executor = new (_observable || _load_observable()).SingletonExecutor(); + const source = new _rxjsBundlesRxMinJs.Subject(); const result = executor.execute(source); expect(executor.isExecuting()).toBe(true); source.next(42); source.complete(); - expect(await result).toBe(42); + expect((yield result)).toBe(42); expect(executor.isExecuting()).toBe(false); - }); + })); }); it('completing task by error', () => { - waitsForPromise(async () => { - const executor = new SingletonExecutor(); - const source = new Subject(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const executor = new (_observable || _load_observable()).SingletonExecutor(); + const source = new _rxjsBundlesRxMinJs.Subject(); const result = executor.execute(source); expect(executor.isExecuting()).toBe(true); @@ -739,31 +739,31 @@ describe('nuclide-commons/observable', () => { source.error(42); let thrown = false; try { - await result; + yield result; } catch (e) { expect(e).toBe(42); thrown = true; } expect(executor.isExecuting()).toBe(false); expect(thrown).toBe(true); - }); + })); }); it('scheduling second task while first is in flight', () => { - waitsForPromise(async () => { - const executor = new SingletonExecutor(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const executor = new (_observable || _load_observable()).SingletonExecutor(); - const source1 = new Subject(); + const source1 = new _rxjsBundlesRxMinJs.Subject(); const result1 = executor.execute(source1); expect(executor.isExecuting()).toBe(true); - const source2 = new Subject(); + const source2 = new _rxjsBundlesRxMinJs.Subject(); const result2 = executor.execute(source2); expect(executor.isExecuting()).toBe(true); let thrown = false; try { - await result1; + yield result1; } catch (e) { expect(e.name).toBe('AbortError'); thrown = true; @@ -774,9 +774,9 @@ describe('nuclide-commons/observable', () => { source2.next(42); source2.complete(); - expect(await result2).toBe(42); + expect((yield result2)).toBe(42); expect(executor.isExecuting()).toBe(false); - }); + })); }); }); @@ -787,9 +787,9 @@ describe('nuclide-commons/observable', () => { }); it('subscribes to the observable synchronously', () => { - const source = Observable.never(); + const source = _rxjsBundlesRxMinJs.Observable.never(); const spy = spyOn(source, 'subscribe').andCallThrough(); - const sub = source.let(poll(10)).subscribe(); + const sub = source.let((0, (_observable || _load_observable()).poll)(10)).subscribe(); expect(spy.callCount).toBe(1); sub.unsubscribe(); }); @@ -799,11 +799,11 @@ describe('nuclide-commons/observable', () => { let spy; let mostRecentObserver; runs(() => { - const source = Observable.create(observer => { + const source = _rxjsBundlesRxMinJs.Observable.create(observer => { mostRecentObserver = observer; }); spy = spyOn(source, 'subscribe').andCallThrough(); - sub = source.let(poll(10)).subscribe(); + sub = source.let((0, (_observable || _load_observable()).poll)(10)).subscribe(); expect(spy.callCount).toBe(1); mostRecentObserver.next(); }); @@ -828,12 +828,12 @@ describe('nuclide-commons/observable', () => { it("doesn't resubscribe to the source when you unsubscribe", () => { let spy; runs(() => { - const source = new Subject(); + const source = new _rxjsBundlesRxMinJs.Subject(); spy = spyOn(source, 'subscribe').andCallThrough(); - source - .let(poll(10)) - .take(1) // This will unsubscribe after the first element. - .subscribe(); + source. + let((0, (_observable || _load_observable()).poll)(10)). + take(1) // This will unsubscribe after the first element. + .subscribe(); expect(spy.callCount).toBe(1); source.next(); }); @@ -844,19 +844,19 @@ describe('nuclide-commons/observable', () => { }); it('polls synchronously completing observables', () => { - waitsForPromise(async () => { - const result = await Observable.of('hi') - .let(poll(10)) - .take(2) - .toArray() - .toPromise(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const result = yield _rxjsBundlesRxMinJs.Observable.of('hi'). + let((0, (_observable || _load_observable()).poll)(10)). + take(2). + toArray(). + toPromise(); expect(result).toEqual(['hi', 'hi']); - }); + })); }); }); }); const sleep = n => - new Promise(resolve => { - setTimeout(resolve, n); - }); +new Promise(resolve => { + setTimeout(resolve, n); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/spec/process-spec.js b/modules/nuclide-commons/spec/process-spec.js index 91bd32e9..37a814cc 100644 --- a/modules/nuclide-commons/spec/process-spec.js +++ b/modules/nuclide-commons/spec/process-spec.js @@ -1,41 +1,41 @@ -/** - * 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 - * @format - */ - -import type {ProcessExitMessage} from '../process'; - -import EventEmitter from 'events'; -import {getLogger} from 'log4js'; -import {sleep} from '../promise'; -import child_process from 'child_process'; -import invariant from 'assert'; -import {Observable, Scheduler, Subject} from 'rxjs'; - -import { - spawn, - getOutputStream, - killProcess, - killUnixProcessTree, - logStreamErrors, - observeProcess, - observeProcessRaw, - parsePsOutput, - preventStreamsFromThrowing, - ProcessSystemError, - runCommand, - runCommandDetailed, - scriptifyCommand, - exitEventToMessage, - LOG_CATEGORY, -} from '../process'; +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + + + + + + + + + + + + + +var _events = _interopRequireDefault(require('events'));var _log4js; +function _load_log4js() {return _log4js = require('log4js');}var _promise; +function _load_promise() {return _promise = require('../promise');} +var _child_process = _interopRequireDefault(require('child_process')); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _process; + +function _load_process() {return _process = require('../process');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + + + + + + + + + + + + + + + + describe('commons-node/process', () => { let origPlatform; @@ -44,214 +44,214 @@ describe('commons-node/process', () => { origPlatform = process.platform; // Use a fake platform so the platform's PATH is not used in case the test is run on a platform // that requires special handling (like OS X). - Object.defineProperty(process, 'platform', {value: 'MockMock'}); + Object.defineProperty(process, 'platform', { value: 'MockMock' }); }); afterEach(() => { - Object.defineProperty(process, 'platform', {value: origPlatform}); + Object.defineProperty(process, 'platform', { value: origPlatform }); }); describe('process.killProcess', () => { it('should only kill the process when `killTree` is false', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { const proc = { - kill: jasmine.createSpy(), - }; + kill: jasmine.createSpy() }; + spyOn(console, 'log'); // suppress log printing - await killProcess((proc: any), false); + yield (0, (_process || _load_process()).killProcess)(proc, false); expect(proc.kill).toHaveBeenCalled(); - }); + })); }); it('should kill the process tree when `killTree` is true', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { jasmine.useRealClock(); // Create a tree that's more than level child deep. - const proc = child_process.spawn('bash', [ - '-c', - '( (sleep 1000)& sleep 1000 )& wait', - ]); + const proc = _child_process.default.spawn('bash', [ + '-c', + '( (sleep 1000)& sleep 1000 )& wait']); + spyOn(console, 'log'); // suppress log printing spyOn(process, 'kill').andCallThrough(); - await sleep(250); // Give some time for the processes to spawn. - await killUnixProcessTree(proc); + yield (0, (_promise || _load_promise()).sleep)(250); // Give some time for the processes to spawn. + yield (0, (_process || _load_process()).killUnixProcessTree)(proc); expect(process.kill.callCount).toBeGreaterThan(2); - }); + })); }); it('should kill the process tree on windows when `killTree` is true', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { const proc = { - pid: 123, - }; + pid: 123 }; + spyOn(console, 'log'); // suppress log printing - Object.defineProperty(process, 'platform', {value: 'win32'}); - spyOn(child_process, 'exec'); - await killProcess((proc: any), true); - expect(child_process.exec.calls.length).toBe(1); - expect(child_process.exec.calls[0].args[0]).toBe( - `taskkill /pid ${proc.pid} /T /F`, - ); - }); + Object.defineProperty(process, 'platform', { value: 'win32' }); + spyOn(_child_process.default, 'exec'); + yield (0, (_process || _load_process()).killProcess)(proc, true); + expect(_child_process.default.exec.calls.length).toBe(1); + expect(_child_process.default.exec.calls[0].args[0]).toBe( + `taskkill /pid ${proc.pid} /T /F`); + + })); }); }); describe('process.parsePsOutput', () => { it('parse `ps` unix output', () => { const unixPsOut = - ' PPID PID COMM\n' + - ' 0 1 /sbin/launchd\n' + - ' 1 42 command with spaces'; - const processList = parsePsOutput(unixPsOut); + ' PPID PID COMM\n' + + ' 0 1 /sbin/launchd\n' + + ' 1 42 command with spaces'; + const processList = (0, (_process || _load_process()).parsePsOutput)(unixPsOut); expect(processList).toEqual([ - { - command: '/sbin/launchd', - pid: 1, - parentPid: 0, - commandWithArgs: '/sbin/launchd', - }, - { - command: 'command with spaces', - pid: 42, - parentPid: 1, - commandWithArgs: 'command with spaces', - }, - ]); + { + command: '/sbin/launchd', + pid: 1, + parentPid: 0, + commandWithArgs: '/sbin/launchd' }, + + { + command: 'command with spaces', + pid: 42, + parentPid: 1, + commandWithArgs: 'command with spaces' }]); + + }); it('parse `ps` unix output with command arguments', () => { const unixPsOut = - ' PPID PID COMM\n' + - ' 0 1 /sbin/launchd\n' + - ' 1 42 command with spaces'; + ' PPID PID COMM\n' + + ' 0 1 /sbin/launchd\n' + + ' 1 42 command with spaces'; const unixPsOutWithArgs = - ' PID ARGS\n' + - ' 1 /sbin/launchd\n' + - ' 42 command with spaces and some more arguments'; + ' PID ARGS\n' + + ' 1 /sbin/launchd\n' + + ' 42 command with spaces and some more arguments'; - const processList = parsePsOutput(unixPsOut, unixPsOutWithArgs); + const processList = (0, (_process || _load_process()).parsePsOutput)(unixPsOut, unixPsOutWithArgs); expect(processList).toEqual([ - { - command: '/sbin/launchd', - pid: 1, - parentPid: 0, - commandWithArgs: '/sbin/launchd', - }, - { - command: 'command with spaces', - pid: 42, - parentPid: 1, - commandWithArgs: 'command with spaces and some more arguments', - }, - ]); + { + command: '/sbin/launchd', + pid: 1, + parentPid: 0, + commandWithArgs: '/sbin/launchd' }, + + { + command: 'command with spaces', + pid: 42, + parentPid: 1, + commandWithArgs: 'command with spaces and some more arguments' }]); + + }); it('parse `ps` windows output', () => { const windowsProcessOut = - 'ParentProcessId ProcessId Name\r\n' + - ' 0 4 System Process\r\n' + - ' 4 228 smss.exe'; + 'ParentProcessId ProcessId Name\r\n' + + ' 0 4 System Process\r\n' + + ' 4 228 smss.exe'; - const processList = parsePsOutput(windowsProcessOut); + const processList = (0, (_process || _load_process()).parsePsOutput)(windowsProcessOut); expect(processList).toEqual([ - { - command: 'System Process', - pid: 4, - parentPid: 0, - commandWithArgs: 'System Process', - }, - { - command: 'smss.exe', - pid: 228, - parentPid: 4, - commandWithArgs: 'smss.exe', - }, - ]); + { + command: 'System Process', + pid: 4, + parentPid: 0, + commandWithArgs: 'System Process' }, + + { + command: 'smss.exe', + pid: 228, + parentPid: 4, + commandWithArgs: 'smss.exe' }]); + + }); }); describe('getOutputStream', () => { it('captures stdout, stderr and exitCode', () => { - waitsForPromise(async () => { - const child = child_process.spawn(process.execPath, [ - '-e', - 'console.error("stderr"); console.log("std out"); process.exit(0);', - ]); - const results = await getOutputStream(child) - .toArray() - .toPromise(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const child = _child_process.default.spawn(process.execPath, [ + '-e', + 'console.error("stderr"); console.log("std out"); process.exit(0);']); + + const results = yield (0, (_process || _load_process()).getOutputStream)(child). + toArray(). + toPromise(); expect(results).toEqual([ - {kind: 'stderr', data: 'stderr\n'}, - {kind: 'stdout', data: 'std out\n'}, - {kind: 'exit', exitCode: 0, signal: null}, - ]); - }); + { kind: 'stderr', data: 'stderr\n' }, + { kind: 'stdout', data: 'std out\n' }, + { kind: 'exit', exitCode: 0, signal: null }]); + + })); }); it('errors on nonzero exit codes by default', () => { - waitsForPromise(async () => { - const child = child_process.spawn(process.execPath, [ - '-e', - 'console.error("stderr"); console.log("std out"); process.exit(42);', - ]); - const results = await getOutputStream(child) - // $FlowIssue: Add materialize to type defs - .materialize() - .toArray() - .toPromise(); - expect(results.map(notification => notification.kind)).toEqual([ - 'N', - 'N', - 'E', - ]); - const {error} = results[2]; + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const child = _child_process.default.spawn(process.execPath, [ + '-e', + 'console.error("stderr"); console.log("std out"); process.exit(42);']); + + const results = yield (0, (_process || _load_process()).getOutputStream)(child) + // $FlowIssue: Add materialize to type defs + .materialize(). + toArray(). + toPromise(); + expect(results.map(function (notification) {return notification.kind;})).toEqual([ + 'N', + 'N', + 'E']); + + const { error } = results[2]; expect(error.name).toBe('ProcessExitError'); expect(error.exitCode).toBe(42); expect(error.stderr).toBe('stderr\n'); - }); + })); }); it('accumulates the first `exitErrorBufferSize` bytes of stderr for the exit error', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { let error; - const child = child_process.spawn(process.execPath, [ - '-e', - 'console.error("stderr"); process.exit(42);', - ]); + const child = _child_process.default.spawn(process.execPath, [ + '-e', + 'console.error("stderr"); process.exit(42);']); + try { - await getOutputStream(child, { + yield (0, (_process || _load_process()).getOutputStream)(child, { exitErrorBufferSize: 2, - isExitError: () => true, - }) - .toArray() - .toPromise(); + isExitError: function () {return true;} }). + + toArray(). + toPromise(); } catch (err) { error = err; } - expect(error).toBeDefined(); - invariant(error != null); + expect(error).toBeDefined();if (!( + error != null)) {throw new Error('Invariant violation: "error != null"');} expect(error.stderr).toBe('st'); - }); + })); }); }); describe('spawn', () => { it('errors when the process does', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { spyOn(console, 'log'); // suppress log printing - const processStream = spawn('fakeCommand'); + const processStream = (0, (_process || _load_process()).spawn)('fakeCommand'); let error; try { - await processStream.toPromise(); + yield processStream.toPromise(); } catch (err) { error = err; } - expect(error).toBeDefined(); - invariant(error); + expect(error).toBeDefined();if (! + error) {throw new Error('Invariant violation: "error"');} expect(error.code).toBe('ENOENT'); expect(error.name).toBe('ProcessSystemError'); - }); + })); }); // Node delays the emission of the error until after the process is returned so that you have a @@ -259,57 +259,57 @@ describe('commons-node/process', () => { // event-emitter APIs, so we can do better and not emit the process if there was an error // spawning it. it('errors before emitting the process', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { spyOn(console, 'log'); // suppress log printing let proc; - await spawn('fakeCommand') - .do(p => { - proc = p; - }) - .catch(err => { - expect(proc).toBeUndefined(); - expect(err.code).toBe('ENOENT'); - expect(err.name).toBe('ProcessSystemError'); - return Observable.empty(); - }) - .toPromise(); - }); + yield (0, (_process || _load_process()).spawn)('fakeCommand'). + do(function (p) { + proc = p; + }). + catch(function (err) { + expect(proc).toBeUndefined(); + expect(err.code).toBe('ENOENT'); + expect(err.name).toBe('ProcessSystemError'); + return _rxjsBundlesRxMinJs.Observable.empty(); + }). + toPromise(); + })); }); it('leaves an error handler when you unsubscribe', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { spyOn(console, 'log'); // suppress log printing let resolve; - const promise = new Promise(r => { + const promise = new Promise(function (r) { resolve = r; }); - const sub = spawn('cat') - // If we subscribe synchronously, and it emits synchronously, `sub` won't have been - // assigned yet in our `subscribe()` callback, so we use the async scheduler. - .subscribeOn(Scheduler.async) - .subscribe(proc => { - // As soon as we have a process, unsubscribe. This will happen before the error is - // thrown. - sub.unsubscribe(); - - // Make sure that the error handler is still registered. If it isn't, and the process - // errors, node will consider the error unhandled and we'll get a redbox. - expect(proc.listenerCount('error')).toBe(1); - - resolve(); - }); - await promise; - }); + const sub = (0, (_process || _load_process()).spawn)('cat') + // If we subscribe synchronously, and it emits synchronously, `sub` won't have been + // assigned yet in our `subscribe()` callback, so we use the async scheduler. + .subscribeOn(_rxjsBundlesRxMinJs.Scheduler.async). + subscribe(function (proc) { + // As soon as we have a process, unsubscribe. This will happen before the error is + // thrown. + sub.unsubscribe(); + + // Make sure that the error handler is still registered. If it isn't, and the process + // errors, node will consider the error unhandled and we'll get a redbox. + expect(proc.listenerCount('error')).toBe(1); + + resolve(); + }); + yield promise; + })); }); it('can be retried', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { spyOn(console, 'log'); // suppress log printing - spyOn(child_process, 'spawn'); + spyOn(_child_process.default, 'spawn'); try { - await spawn('fakeCommand') - .retryWhen(errors => - errors.scan((errorCount, err) => { + yield (0, (_process || _load_process()).spawn)('fakeCommand'). + retryWhen(function (errors) {return ( + errors.scan(function (errorCount, err) { // If this is the third time the process has errored (i.e. the have already been // two errors before), stop retrying. (We try 3 times because because Rx 3 and 4 // have bugs with retrying shared observables that would give false negatives for @@ -318,125 +318,125 @@ describe('commons-node/process', () => { throw err; } return errorCount + 1; - }, 0), - ) - .toPromise(); + }, 0));}). + + toPromise(); } catch (err) {} - expect(child_process.spawn.callCount).toBe(3); - }); + expect(_child_process.default.spawn.callCount).toBe(3); + })); }); it('can be timed out', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { let error; let proc; try { - await spawn('sleep', ['10000'], {timeout: 1}) - .do(p => { - proc = p; - spyOn(proc, 'kill'); - }) - .toPromise(); + yield (0, (_process || _load_process()).spawn)('sleep', ['10000'], { timeout: 1 }). + do(function (p) { + proc = p; + spyOn(proc, 'kill'); + }). + toPromise(); } catch (err) { error = err; - } - invariant(proc != null); - invariant(error != null); + }if (!( + proc != null)) {throw new Error('Invariant violation: "proc != null"');}if (!( + error != null)) {throw new Error('Invariant violation: "error != null"');} expect(error.name).toBe('ProcessTimeoutError'); expect(proc.kill).toHaveBeenCalled(); - }); + })); }); }); describe('observeProcess', () => { it('errors when the process does', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { spyOn(console, 'log'); // suppress log printing - const processStream = observeProcess('fakeCommand', []); + const processStream = (0, (_process || _load_process()).observeProcess)('fakeCommand', []); let error; try { - await processStream.toPromise(); + yield processStream.toPromise(); } catch (err) { error = err; } - expect(error).toBeDefined(); - invariant(error); + expect(error).toBeDefined();if (! + error) {throw new Error('Invariant violation: "error"');} expect(error.code).toBe('ENOENT'); expect(error.name).toBe('ProcessSystemError'); - }); + })); }); it('errors on nonzero exit codes by default', () => { - waitsForPromise(async () => { - const results = await observeProcess(process.execPath, [ - '-e', - 'console.error("stderr"); console.log("std out"); process.exit(42);', - ]) - // $FlowIssue: Add materialize to type defs - .materialize() - .toArray() - .toPromise(); - expect(results.map(notification => notification.kind)).toEqual([ - 'N', - 'N', - 'E', - ]); - const {error} = results[2]; + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const results = yield (0, (_process || _load_process()).observeProcess)(process.execPath, [ + '-e', + 'console.error("stderr"); console.log("std out"); process.exit(42);']) + + // $FlowIssue: Add materialize to type defs + .materialize(). + toArray(). + toPromise(); + expect(results.map(function (notification) {return notification.kind;})).toEqual([ + 'N', + 'N', + 'E']); + + const { error } = results[2]; expect(error.name).toBe('ProcessExitError'); expect(error.exitCode).toBe(42); expect(error.stderr).toBe('stderr\n'); - }); + })); }); it("doesn't get an exit message when there's an exit error", () => { - waitsForPromise(async () => { - const results = await observeProcess(process.execPath, [ - '-e', - 'process.exit(42);', - ]) - // $FlowIssue: Add materialize to type defs - .materialize() - .toArray() - .toPromise(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const results = yield (0, (_process || _load_process()).observeProcess)(process.execPath, [ + '-e', + 'process.exit(42);']) + + // $FlowIssue: Add materialize to type defs + .materialize(). + toArray(). + toPromise(); expect(results.length).toBe(1); expect(results[0].kind).toBe('E'); - }); + })); }); it('accumulates the first `exitErrorBufferSize` bytes of stderr for the exit error', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { let error; try { - await observeProcess( - process.execPath, - ['-e', 'console.error("stderr"); process.exit(42);'], - {exitErrorBufferSize: 2, isExitError: () => true}, - ) - .toArray() - .toPromise(); + yield (0, (_process || _load_process()).observeProcess)( + process.execPath, + ['-e', 'console.error("stderr"); process.exit(42);'], + { exitErrorBufferSize: 2, isExitError: function () {return true;} }). + + toArray(). + toPromise(); } catch (err) { error = err; } - expect(error).toBeDefined(); - invariant(error != null); + expect(error).toBeDefined();if (!( + error != null)) {throw new Error('Invariant violation: "error != null"');} expect(error.stderr).toBe('st'); - }); + })); }); }); describe('observeProcessRaw', () => { it("doesn't split on line breaks", () => { spyOn(console, 'log'); // suppress log printing - waitsForPromise({timeout: 1000}, async () => { - const event = await observeProcessRaw(process.execPath, [ - '-e', - 'process.stdout.write("stdout1\\nstdout2\\n"); process.exit(1)', - ]) - .take(1) - .toPromise(); - invariant(event.kind === 'stdout'); + waitsForPromise({ timeout: 1000 }, (0, _asyncToGenerator.default)(function* () { + const event = yield (0, (_process || _load_process()).observeProcessRaw)(process.execPath, [ + '-e', + 'process.stdout.write("stdout1\\nstdout2\\n"); process.exit(1)']). + + take(1). + toPromise();if (!( + event.kind === 'stdout')) {throw new Error('Invariant violation: "event.kind === \'stdout\'"');} expect(event.data).toBe('stdout1\nstdout2\n'); - }); + })); }); }); @@ -451,145 +451,145 @@ describe('commons-node/process', () => { } it('sends the stdin to the process', () => { - waitsForPromise(async () => { - const output = await runCommand('cat', [], { - input: 'hello', - }).toPromise(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const output = yield (0, (_process || _load_process()).runCommand)('cat', [], { + input: 'hello' }). + toPromise(); expect(output).toBe('hello'); - }); + })); }); it('sends a stream of stdin to the process', () => { - waitsForPromise(async () => { - const input = new Subject(); - const outputPromise = runCommand('cat', [], { - input, - }).toPromise(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const input = new _rxjsBundlesRxMinJs.Subject(); + const outputPromise = (0, (_process || _load_process()).runCommand)('cat', [], { + input }). + toPromise(); input.next('hello'); input.next(' '); input.next('world'); input.complete(); - expect(await outputPromise).toBe('hello world'); - }); + expect((yield outputPromise)).toBe('hello world'); + })); }); it('enforces maxBuffer', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { let error; try { - await runCommand('yes', [], {maxBuffer: 100}).toPromise(); + yield (0, (_process || _load_process()).runCommand)('yes', [], { maxBuffer: 100 }).toPromise(); } catch (err) { error = err; - } - invariant(error != null); + }if (!( + error != null)) {throw new Error('Invariant violation: "error != null"');} expect(error.message).toContain('maxBuffer'); - }); + })); }); it('returns stdout of the running process', () => { - waitsForPromise(async () => { - const val = await runCommand('echo', ['-n', 'foo'], { - env: process.env, - }).toPromise(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const val = yield (0, (_process || _load_process()).runCommand)('echo', ['-n', 'foo'], { + env: process.env }). + toPromise(); expect(val).toEqual('foo'); - }); + })); }); it("throws an error if the process can't be spawned", () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { let error; try { - await runCommand('fakeCommand').toPromise(); + yield (0, (_process || _load_process()).runCommand)('fakeCommand').toPromise(); } catch (err) { error = err; - } - invariant(error != null); + }if (!( + error != null)) {throw new Error('Invariant violation: "error != null"');} expect(error.code).toBe('ENOENT'); expect(error.name).toBe('ProcessSystemError'); - }); + })); }); it('throws an error if the exit code !== 0', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { let error; try { - await runCommand(process.execPath, [ - '-e', - 'process.exit(1)', - ]).toPromise(); + yield (0, (_process || _load_process()).runCommand)(process.execPath, [ + '-e', + 'process.exit(1)']). + toPromise(); } catch (err) { error = err; - } - invariant(error != null); + }if (!( + error != null)) {throw new Error('Invariant violation: "error != null"');} expect(error.name).toBe('ProcessExitError'); expect(error.exitCode).toBe(1); - }); + })); }); it('includes stdout and stderr in ProcessExitErrors', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { let error; try { - await runCommand(process.execPath, [ - '-e', - 'process.stderr.write("oopsy"); process.stdout.write("daisy"); process.exit(1)', - ]).toPromise(); + yield (0, (_process || _load_process()).runCommand)(process.execPath, [ + '-e', + 'process.stderr.write("oopsy"); process.stdout.write("daisy"); process.exit(1)']). + toPromise(); } catch (err) { error = err; - } - invariant(error != null); + }if (!( + error != null)) {throw new Error('Invariant violation: "error != null"');} expect(error.name).toBe('ProcessExitError'); expect(error.stderr).toBe('oopsy'); expect(error.stdout).toBe('daisy'); - }); + })); }); it('accumulates the stderr if the process exits with a non-zero code', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { let error; try { - await runCommand(process.execPath, [ - '-e', - 'process.stderr.write("oopsy"); process.exit(1)', - ]).toPromise(); + yield (0, (_process || _load_process()).runCommand)(process.execPath, [ + '-e', + 'process.stderr.write("oopsy"); process.exit(1)']). + toPromise(); } catch (err) { error = err; - } - invariant(error != null); + }if (!( + error != null)) {throw new Error('Invariant violation: "error != null"');} expect(error.stderr).toBe('oopsy'); - }); + })); }); // Previously we had a bug where we mutated the seed and subsequent subscriptions would use the // mutated value. it("doesn't share a mutable seed (regression test)", () => { - waitsForPromise(async () => { - const observable = runCommand(process.execPath, [ - '-e', - 'process.stdout.write("hello"); process.exit(0)', - ]); - await observable.toPromise(); - expect(await observable.toPromise()).toBe('hello'); - }); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const observable = (0, (_process || _load_process()).runCommand)(process.execPath, [ + '-e', + 'process.stdout.write("hello"); process.exit(0)']); + + yield observable.toPromise(); + expect((yield observable.toPromise())).toBe('hello'); + })); }); describe('checkOutput compatibility', () => { if (origPlatform !== 'win32') { it('returns stdout of the running process', () => { - waitsForPromise(async () => { - const val = await runCommand('echo', ['-n', 'foo'], { - env: process.env, - }).toPromise(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const val = yield (0, (_process || _load_process()).runCommand)('echo', ['-n', 'foo'], { + env: process.env }). + toPromise(); expect(val).toEqual('foo'); - }); + })); }); it('throws an error if the exit code !== 0', () => { - waitsForPromise({shouldReject: true}, async () => { - await runCommand(process.execPath, [ - '-e', - 'process.exit(1)', - ]).toPromise(); - }); + waitsForPromise({ shouldReject: true }, (0, _asyncToGenerator.default)(function* () { + yield (0, (_process || _load_process()).runCommand)(process.execPath, [ + '-e', + 'process.exit(1)']). + toPromise(); + })); }); } }); @@ -606,105 +606,105 @@ describe('commons-node/process', () => { } it('sends the stdin to the process', () => { - waitsForPromise(async () => { - const output = await runCommandDetailed('cat', [], { - input: 'hello', - }).toPromise(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const output = yield (0, (_process || _load_process()).runCommandDetailed)('cat', [], { + input: 'hello' }). + toPromise(); expect(output.stdout).toBe('hello'); - }); + })); }); it('enforces maxBuffer', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { let error; try { - await runCommandDetailed('yes', [], {maxBuffer: 100}).toPromise(); + yield (0, (_process || _load_process()).runCommandDetailed)('yes', [], { maxBuffer: 100 }).toPromise(); } catch (err) { error = err; - } - invariant(error != null); + }if (!( + error != null)) {throw new Error('Invariant violation: "error != null"');} expect(error.message).toContain('maxBuffer'); - }); + })); }); it('returns stdout, stderr, and the exit code of the running process', () => { - waitsForPromise(async () => { - const val = await runCommandDetailed(process.execPath, [ - '-e', - 'process.stdout.write("out"); process.stderr.write("err"); process.exit(0)', - ]).toPromise(); - expect(val).toEqual({stdout: 'out', stderr: 'err', exitCode: 0}); - }); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const val = yield (0, (_process || _load_process()).runCommandDetailed)(process.execPath, [ + '-e', + 'process.stdout.write("out"); process.stderr.write("err"); process.exit(0)']). + toPromise(); + expect(val).toEqual({ stdout: 'out', stderr: 'err', exitCode: 0 }); + })); }); it("throws an error if the process can't be spawned", () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { let error; try { - await runCommandDetailed('fakeCommand').toPromise(); + yield (0, (_process || _load_process()).runCommandDetailed)('fakeCommand').toPromise(); } catch (err) { error = err; - } - invariant(error != null); + }if (!( + error != null)) {throw new Error('Invariant violation: "error != null"');} expect(error.code).toBe('ENOENT'); expect(error.name).toBe('ProcessSystemError'); - }); + })); }); it('throws an error if the exit code !== 0', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { let error; try { - await runCommandDetailed(process.execPath, [ - '-e', - 'process.exit(1)', - ]).toPromise(); + yield (0, (_process || _load_process()).runCommandDetailed)(process.execPath, [ + '-e', + 'process.exit(1)']). + toPromise(); } catch (err) { error = err; - } - invariant(error != null); + }if (!( + error != null)) {throw new Error('Invariant violation: "error != null"');} expect(error.name).toBe('ProcessExitError'); expect(error.exitCode).toBe(1); - }); + })); }); it('accumulates the stderr if the process exits with a non-zero code', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { let error; try { - await runCommandDetailed(process.execPath, [ - '-e', - 'process.stderr.write("oopsy"); process.exit(1)', - ]).toPromise(); + yield (0, (_process || _load_process()).runCommandDetailed)(process.execPath, [ + '-e', + 'process.stderr.write("oopsy"); process.exit(1)']). + toPromise(); } catch (err) { error = err; - } - invariant(error != null); + }if (!( + error != null)) {throw new Error('Invariant violation: "error != null"');} expect(error.stderr).toBe('oopsy'); - }); + })); }); }); describe('exitEventToMessage', () => { it('exitCode', () => { - expect(exitEventToMessage(makeExitMessage(1))).toBe('exit code 1'); + expect((0, (_process || _load_process()).exitEventToMessage)(makeExitMessage(1))).toBe('exit code 1'); }); it('signal', () => { expect( - exitEventToMessage({kind: 'exit', exitCode: null, signal: 'SIGTERM'}), - ).toBe('signal SIGTERM'); + (0, (_process || _load_process()).exitEventToMessage)({ kind: 'exit', exitCode: null, signal: 'SIGTERM' })). + toBe('signal SIGTERM'); }); }); describe('preventStreamsFromThrowing', () => { - let proc: child_process$ChildProcess; + let proc; beforeEach(() => { - proc = ({ - stdin: new EventEmitter(), - stdout: new EventEmitter(), - stderr: new EventEmitter(), - }: any); + proc = { + stdin: new _events.default(), + stdout: new _events.default(), + stderr: new _events.default() }; + spyOn(proc.stdin, 'addListener').andCallThrough(); spyOn(proc.stdout, 'addListener').andCallThrough(); spyOn(proc.stderr, 'addListener').andCallThrough(); @@ -714,48 +714,48 @@ describe('commons-node/process', () => { }); it('adds listeners', () => { - preventStreamsFromThrowing(proc); + (0, (_process || _load_process()).preventStreamsFromThrowing)(proc); expect(proc.stdin.addListener).toHaveBeenCalledWith( - 'error', - jasmine.any(Function), - ); + 'error', + jasmine.any(Function)); + expect(proc.stdout.addListener).toHaveBeenCalledWith( - 'error', - jasmine.any(Function), - ); + 'error', + jasmine.any(Function)); + expect(proc.stderr.addListener).toHaveBeenCalledWith( - 'error', - jasmine.any(Function), - ); + 'error', + jasmine.any(Function)); + }); it('removes listeners when disposed', () => { - const disposable = preventStreamsFromThrowing(proc); + const disposable = (0, (_process || _load_process()).preventStreamsFromThrowing)(proc); disposable.dispose(); expect(proc.stdin.removeListener).toHaveBeenCalledWith( - 'error', - jasmine.any(Function), - ); + 'error', + jasmine.any(Function)); + expect(proc.stdout.removeListener).toHaveBeenCalledWith( - 'error', - jasmine.any(Function), - ); + 'error', + jasmine.any(Function)); + expect(proc.stderr.removeListener).toHaveBeenCalledWith( - 'error', - jasmine.any(Function), - ); + 'error', + jasmine.any(Function)); + }); }); describe('logStreamErrors', () => { - const logger = getLogger(LOG_CATEGORY); - let proc: child_process$ChildProcess; + const logger = (0, (_log4js || _load_log4js()).getLogger)((_process || _load_process()).LOG_CATEGORY); + let proc; beforeEach(() => { - proc = ({ - stdin: new EventEmitter(), - stdout: new EventEmitter(), - stderr: new EventEmitter(), - }: any); + proc = { + stdin: new _events.default(), + stdout: new _events.default(), + stderr: new _events.default() }; + // Add a no-op listener so the error events aren't thrown. proc.stdin.on('error', () => {}); @@ -764,14 +764,14 @@ describe('commons-node/process', () => { }); it('logs errors', () => { - logStreamErrors(proc, 'test', [], {}); + (0, (_process || _load_process()).logStreamErrors)(proc, 'test', [], {}); spyOn(logger, 'error'); proc.stderr.emit('error', new Error('Test error')); expect(logger.error).toHaveBeenCalled(); }); it("doesn't log when disposed", () => { - const disposable = logStreamErrors(proc, 'test', [], {}); + const disposable = (0, (_process || _load_process()).logStreamErrors)(proc, 'test', [], {}); spyOn(logger, 'error'); disposable.dispose(); proc.stderr.emit('error', new Error('Test error')); @@ -781,14 +781,14 @@ describe('commons-node/process', () => { describe('ProcessSystemError', () => { it('contains the correct properties', () => { - const proc = (({}: any): child_process$ChildProcess); + const proc = {}; const originalError = { errno: 2, code: 'ETEST', path: 'path value', - syscall: 'syscall value', - }; - const err = new ProcessSystemError(originalError, proc); + syscall: 'syscall value' }; + + const err = new (_process || _load_process()).ProcessSystemError(originalError, proc); expect(err.errno).toBe(2); expect(err.code).toBe('ETEST'); expect(err.path).toBe('path value'); @@ -800,26 +800,28 @@ describe('commons-node/process', () => { describe('scriptifyCommand', () => { if (process.platform === 'linux') { it('escapes correctly on linux', () => { - waitsForPromise(async () => { - const output = await runCommand( - ...scriptifyCommand('echo', [ - 'a\\b c\\\\d e\\\\\\f g\\\\\\\\h "dubs" \'singles\'', - 'one two', - ]), - ).toPromise(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const output = yield (0, (_process || _load_process()).runCommand)( + ...(0, (_process || _load_process()).scriptifyCommand)('echo', [ + 'a\\b c\\\\d e\\\\\\f g\\\\\\\\h "dubs" \'singles\'', + 'one two'])). + + toPromise(); expect(output.trim()).toBe( - 'a\\b c\\\\d e\\\\\\f g\\\\\\\\h "dubs" \'singles\' one two', - ); - }); + 'a\\b c\\\\d e\\\\\\f g\\\\\\\\h "dubs" \'singles\' one two'); + + })); }); } }); -}); - -function makeExitMessage(exitCode: number): ProcessExitMessage { - return { - kind: 'exit', - exitCode, - signal: null, - }; -} +}); /** + * 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. + * + * + * @format + */function makeExitMessage(exitCode) {return { kind: 'exit', exitCode, signal: null };} \ No newline at end of file diff --git a/modules/nuclide-commons/spec/promise-spec.js b/modules/nuclide-commons/spec/promise-spec.js index 04348598..49d308df 100644 --- a/modules/nuclide-commons/spec/promise-spec.js +++ b/modules/nuclide-commons/spec/promise-spec.js @@ -1,655 +1,681 @@ -/** - * 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 - * @format - */ - -/* eslint-disable prefer-promise-reject-errors */ - -import { - asyncFind, - denodeify, - serializeAsyncCall, - asyncLimit, - asyncFilter, - asyncObjFilter, - asyncSome, - lastly, - retryLimit, - RequestSerializer, - TimedOutError, - timeoutPromise, -} from '../promise'; -import invariant from 'assert'; -import {expectAsyncFailure} from '../test-helpers'; - -describe('promises::asyncFind()', () => { - it('Empty list of items should resolve to null.', () => { - let isResolved = false; - let observedResult; - let isRejected = false; - let observedError; - - const args = []; - const test = value => { - throw new Error('Should not be called.'); - }; - - runs(() => { - asyncFind(args, test) - .then(result => { - observedResult = result; - isResolved = true; - }) - .catch(error => { - observedError = error; - isRejected = true; - }); - }); - - waitsFor(() => isResolved || isRejected); - - runs(() => { - expect(isResolved).toBe(true); - expect(observedResult).toBe(null); - expect(isRejected).toBe(false); - expect(observedError).toBe(undefined); - }); - }); - - it('Last item in list resolves.', () => { - let isResolved = false; - let observedResult; - let isRejected = false; - let observedError; - - const args = ['foo', 'bar', 'baz']; - const test = value => { - if (value === 'foo') { - return null; - } else if (value === 'bar') { - return Promise.resolve(null); - } else { - return Promise.resolve('win'); - } - }; - - runs(() => { - asyncFind(args, test) - .then(result => { - observedResult = result; - isResolved = true; - }) - .catch(error => { - observedError = error; - isRejected = true; - }); - }); - - waitsFor(() => isResolved || isRejected); - - runs(() => { - expect(isResolved).toBe(true); - expect(observedResult).toBe('win'); - expect(isRejected).toBe(false); - expect(observedError).toBe(undefined); - }); - }); -}); - -describe('promises::denodeify()', () => { - /** - * Vararg function that assumes that all elements except the last are - * numbers, as the last argument is a callback function. All of the - * other arguments are multiplied together. If the result is not NaN, - * then the callback is called with the product. Otherwise, the callback - * is called with an error. - * - * This function exhibits some of the quirky behavior of Node APIs that - * accept a variable number of arguments in the middle of the parameter list - * rather than at the end. The type signature of this function cannot be - * expressed in Flow. - */ - function asyncProduct(...factors): void { - const callback = factors.pop(); - const product = factors.reduce((previousValue, currentValue) => { - return previousValue * currentValue; - }, 1); - - if (isNaN(product)) { - callback(new Error('product was NaN')); - } else { - callback(null, product); - } - } - - it('resolves Promise when callback succeeds', () => { - const denodeifiedAsyncProduct = denodeify(asyncProduct); - waitsForPromise(async () => { - const trivialProduct = await denodeifiedAsyncProduct(); - expect(trivialProduct).toBe(1); - - const product = await denodeifiedAsyncProduct(1, 2, 3, 4, 5); - expect(product).toBe(120); - }); - }); - - it('rejects Promise when callback fails', () => { - const denodeifiedAsyncProduct = denodeify(asyncProduct); - waitsForPromise(async () => { - await expectAsyncFailure( - denodeifiedAsyncProduct('a', 'b'), - (error: Error) => { - expect(error.message).toBe('product was NaN'); - }, - ); - }); - }); - - function checksReceiver(expectedReceiver, callback) { - if (this === expectedReceiver) { - callback(null, 'winner'); - } else { - callback(new Error('unexpected receiver')); - } - } - - it('result of denodeify propagates receiver as expected', () => { - const denodeifiedChecksReceiver = denodeify(checksReceiver); - - waitsForPromise(async () => { - const receiver = {denodeifiedChecksReceiver}; - const result = await receiver.denodeifiedChecksReceiver(receiver); - expect(result).toBe('winner'); - }); - - waitsForPromise(async () => { - const receiver = {denodeifiedChecksReceiver}; - await expectAsyncFailure( - receiver.denodeifiedChecksReceiver(null), - (error: Error) => { - expect(error.message).toBe('unexpected receiver'); - }, - ); - }); - }); -}); - -describe('promises::serializeAsyncCall()', () => { - it('Returns the same result when called after scheduled', () => { - let i = 0; - const asyncFunSpy = jasmine.createSpy('async'); - const oneAsyncCallAtATime = serializeAsyncCall(() => { - i++; - const resultPromise = waitPromise(10, i); - asyncFunSpy(); - return resultPromise; - }); - // Start an async, and resolve to 1 in 10 ms. - const result1Promise = oneAsyncCallAtATime(); - // Schedule the next async, and resolve to 2 in 20 ms. - const result2Promise = oneAsyncCallAtATime(); - // Reuse scheduled promise and resolve to 2 in 20 ms. - const result3Promise = oneAsyncCallAtATime(); - - advanceClock(11); - // Wait for the promise to call the next chain - // That isn't synchrnously guranteed because it happens on `process.nextTick`. - waitsFor(() => asyncFunSpy.callCount === 2); - waitsForPromise(async () => { - advanceClock(11); - const results = await Promise.all([ - result1Promise, - result2Promise, - result3Promise, - ]); - expect(results).toEqual([1, 2, 2]); - }); - }); - - it('Calls and returns (even if errors) the same number of times if serially called', () => { - waitsForPromise(async () => { - let i = 0; - const oneAsyncCallAtATime = serializeAsyncCall(() => { - i++; - if (i === 4) { - return Promise.reject('ERROR'); - } - return waitPromise(10, i); - }); - const result1Promise = oneAsyncCallAtATime(); - advanceClock(11); - const result1 = await result1Promise; - - const result2Promise = oneAsyncCallAtATime(); - advanceClock(11); - const result2 = await result2Promise; - - const result3Promise = oneAsyncCallAtATime(); - advanceClock(11); - const result3 = await result3Promise; - - const errorPromoise = oneAsyncCallAtATime(); - advanceClock(11); - await expectAsyncFailure(errorPromoise, error => { - expect(error).toBe('ERROR'); - }); - - const result5Promise = oneAsyncCallAtATime(); - advanceClock(11); - const result5 = await result5Promise; - expect([result1, result2, result3, result5]).toEqual([1, 2, 3, 5]); - }); - }); -}); - -describe('promises::asyncLimit()', () => { - beforeEach(() => { - jasmine.useRealClock(); - }); - - it('runs in series if limit is 1', () => { - waitsForPromise(async () => { - const {result, parallelismHistory} = await captureParallelismHistory( - asyncLimit, - [[1, 2, 3], 1, item => waitPromise(10, item + 1)], - ); - expect(parallelismHistory).toEqual([1, 1, 1]); - expect(result).toEqual([2, 3, 4]); - }); - }); - - it('runs with the specified limit, until finishing', () => { - waitsForPromise(async () => { - const {result, parallelismHistory} = await captureParallelismHistory( - asyncLimit, - [ - [1, 2, 3, 4, 5, 6, 7, 8, 9], - 3, - item => waitPromise(10 + item, item - 1), - ], - ); - expect(result).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8]); - expect(parallelismHistory).toEqual([1, 2, 3, 3, 3, 3, 3, 3, 3]); - }); - }); - - it('works when the limit is bigger than the array length', () => { - waitsForPromise(async () => { - const result = await asyncLimit([1, 2, 3], 10, item => - waitPromise(10, item * 2), - ); - expect(result).toEqual([2, 4, 6]); - }); - }); - - it('a rejected promise rejects the whole call with the error', () => { - waitsForPromise(async () => { - await expectAsyncFailure( - asyncLimit([1], 1, async item => { - throw new Error('rejected iterator promise'); - }), - (error: Error) => { - expect(error.message).toBe('rejected iterator promise'); - }, - ); - }); - }); - - it('works when the array is empty', () => { - waitsForPromise(async () => { - const result = await asyncLimit([], 1, () => Promise.resolve()); - expect(result).toEqual([]); - }); - }); -}); - -describe('promises::asyncFilter()', () => { - beforeEach(() => { - jasmine.useRealClock(); - }); - - // eslint-disable-next-line max-len - it('filters an array with an async iterator and maximum parallelization when no limit is specified', () => { - waitsForPromise(async () => { - const { - result: filtered, - parallelismHistory, - } = await captureParallelismHistory(asyncFilter, [ - [1, 2, 3, 4, 5], - item => waitPromise(10 + item, item > 2), - ]); - expect(filtered).toEqual([3, 4, 5]); - expect(parallelismHistory).toEqual([1, 2, 3, 4, 5]); - }); - }); - - it('filters an array with a limit on parallelization', () => { - waitsForPromise(async () => { - const { - result: filtered, - parallelismHistory, - } = await captureParallelismHistory(asyncFilter, [ - [1, 2, 3, 4, 5], - item => waitPromise(10 + item, item > 2), - 3, - ]); - expect(filtered).toEqual([3, 4, 5]); - // Increasing promise resolve time will gurantee maximum parallelization. - expect(parallelismHistory).toEqual([1, 2, 3, 3, 3]); - }); - }); -}); - -describe('promises::asyncObjFilter()', () => { - beforeEach(() => { - jasmine.useRealClock(); - }); - - // eslint-disable-next-line max-len - it('filters an object with an async iterator and maximum parallelization when no limit is specified', () => { - waitsForPromise(async () => { - const { - result: filtered, - parallelismHistory, - } = await captureParallelismHistory(asyncObjFilter, [ - {a: 1, b: 2, c: 3, d: 4, e: 5}, - (value, key) => waitPromise(5 + value, value > 2), - ]); - expect(filtered).toEqual({c: 3, d: 4, e: 5}); - expect(parallelismHistory).toEqual([1, 2, 3, 4, 5]); - }); - }); - - it('filters an array with a limit on parallelization', () => { - waitsForPromise(async () => { - const { - result: filtered, - parallelismHistory, - } = await captureParallelismHistory(asyncObjFilter, [ - {a: 1, b: 2, c: 3, d: 4, e: 5}, - (value, key) => waitPromise(5 + value, value > 2), - 3, - ]); - expect(filtered).toEqual({c: 3, d: 4, e: 5}); - // Increasing promise resolve time will gurantee maximum parallelization. - expect(parallelismHistory).toEqual([1, 2, 3, 3, 3]); - }); - }); -}); - -describe('promises::asyncSome()', () => { - beforeEach(() => { - jasmine.useRealClock(); - }); - - // eslint-disable-next-line max-len - it('some an array with an async iterator and maximum parallelization when no limit is specified', () => { - waitsForPromise(async () => { - const {result, parallelismHistory} = await captureParallelismHistory( - asyncSome, - [[1, 2, 3, 4, 5], item => waitPromise(10, item === 6)], - ); - expect(result).toEqual(false); - expect(parallelismHistory).toEqual([1, 2, 3, 4, 5]); - }); - }); - - it('some an array with a limit on parallelization', () => { - waitsForPromise(async () => { - const {result, parallelismHistory} = await captureParallelismHistory( - asyncSome, - [[1, 2, 3, 4, 5], item => waitPromise(10 + item, item === 5), 3], - ); - expect(result).toEqual(true); - expect(parallelismHistory).toEqual([1, 2, 3, 3, 3]); - }); - }); -}); - -describe('promises::lastly', () => { - it('executes after a resolved promise', () => { - waitsForPromise(async () => { - const spy = jasmine.createSpy('spy'); - const result = await lastly(Promise.resolve(1), spy); - expect(result).toBe(1); - expect(spy).toHaveBeenCalled(); - }); - }); - - it('executes after a rejected promise', () => { - waitsForPromise(async () => { - const spy = jasmine.createSpy('spy'); - await expectAsyncFailure(lastly(Promise.reject(2), spy), err => { - expect(err).toBe(2); - }); - expect(spy).toHaveBeenCalled(); - }); - }); - - it('works for async functions', () => { - waitsForPromise(async () => { - const spy = jasmine.createSpy('spy'); - const result = await lastly(Promise.resolve(1), async () => { - spy(); - }); - expect(result).toBe(1); - expect(spy).toHaveBeenCalled(); - }); - }); -}); - -describe('promises::retryLimit()', () => { - beforeEach(() => { - jasmine.useRealClock(); - }); - - it('retries and fails 2 times before resolving to an acceptable result where limit = 5', () => { - waitsForPromise(async () => { - let succeedAfter = 2; - let calls = 0; - let validationCalls = 0; - const retrialsResult = await retryLimit( - () => { - return new Promise((resolve, reject) => { - calls++; - if (succeedAfter-- === 0) { - resolve('RESULT'); - } else { - reject('ERROR'); - } - }); - }, - result => { - validationCalls++; - return result === 'RESULT'; - }, - 5, - ); - expect(calls).toBe(3); - expect(validationCalls).toBe(1); - expect(retrialsResult).toBe('RESULT'); - }); - }); - - it('retries and fails consistently', () => { - waitsForPromise(async () => { - let calls = 0; - let validationCalls = 0; - const failRetriesPromise = retryLimit( - () => { - calls++; - return Promise.reject('ERROR'); - }, - result => { - validationCalls++; - return result != null; - }, - 2, - ); - await expectAsyncFailure(failRetriesPromise, error => { - expect(error).toBe('ERROR'); - }); - expect(calls).toBe(2); - expect(validationCalls).toBe(0); - }); - }); - - it('accepts a null response', () => { - waitsForPromise(async () => { - let succeedAfter = 2; - let calls = 0; - let validationCalls = 0; - const retryResult = await retryLimit( - () => { - calls++; - if (succeedAfter-- === 0) { - return Promise.resolve(null); - } else { - return Promise.resolve('NOT_GOOD'); - } - }, - result => { - validationCalls++; - return result == null; - }, - 5, - ); - expect(retryResult).toBe(null); - expect(calls).toBe(3); - expect(validationCalls).toBe(3); - }); - }); - - it('no valid response is ever got', () => { - waitsForPromise(async () => { - const nonValidRetriesPromise = retryLimit( - () => { - return Promise.resolve('A'); - }, - result => { - return result === 'B'; - }, - 2, - ); - await expectAsyncFailure(nonValidRetriesPromise, error => { - expect(error.message).toBe('No valid response found!'); - }); - }); - }); -}); - -describe('promises::RequestSerializer()', () => { - let requestSerializer: RequestSerializer = (null: any); - - beforeEach(() => { - jasmine.useRealClock(); - requestSerializer = new RequestSerializer(); - }); - - it('gets outdated result for old promises resolving after newer calls', () => { - waitsForPromise(async () => { - const oldPromise = requestSerializer.run(waitPromise(10, 'OLD')); - const newPromise = requestSerializer.run(waitPromise(5, 'NEW')); - const {status: oldStatus} = await oldPromise; - expect(oldStatus).toBe('outdated'); - const newResult = await newPromise; - invariant(newResult.status === 'success'); - expect(newResult.result).toBe('NEW'); - }); - }); - - it('waitForLatestResult: waits for the latest result', () => { - waitsForPromise(async () => { - requestSerializer.run(waitPromise(5, 'OLD')); - requestSerializer.run(waitPromise(10, 'NEW')); - const latestResult = await requestSerializer.waitForLatestResult(); - expect(latestResult).toBe('NEW'); - }); - }); - - it('waitForLatestResult: waits even if the first run did not kick off', () => { - waitsForPromise(async () => { - const latestResultPromise = requestSerializer.waitForLatestResult(); - requestSerializer.run(waitPromise(10, 'RESULT')); - const latestResult = await latestResultPromise; - expect(latestResult).toBe('RESULT'); - }); - }); - - it('waitForLatestResult: does not wait for the first, if the second resolves faster', () => { - waitsForPromise(async () => { - requestSerializer.run(waitPromise(1000000, 'OLD')); // This will never resolve. - requestSerializer.run(waitPromise(10, 'NEW')); - const latestResult = await requestSerializer.waitForLatestResult(); - expect(latestResult).toBe('NEW'); - }); - }); -}); - -describe('timeoutPromise', () => { - it('should resolve normally if within the timeout', () => { - waitsForPromise(async () => { - const inputPromise = new Promise(resolve => resolve('foo')); - const outputPromise = timeoutPromise(inputPromise, 1000); - expect(await outputPromise).toBe('foo'); - }); - }); - - it('should reject if the given promise rejects', () => { - waitsForPromise(async () => { - const inputPromise = new Promise((resolve, reject) => reject('foo')); - const outputPromise = timeoutPromise(inputPromise, 1000).catch( - value => `rejected with ${value}`, - ); - expect(await outputPromise).toBe('rejected with foo'); - }); - }); - - it('should reject if the given promise takes too long', () => { - waitsForPromise(async () => { - const inputPromise = new Promise(resolve => setTimeout(resolve, 2000)); - const outputPromise = timeoutPromise(inputPromise, 1000).catch( - value => value, - ); - advanceClock(1500); - expect(await outputPromise).toEqual(new TimedOutError(1000)); - }); - }); -}); - -async function captureParallelismHistory( - asyncFunction: (...args: Array) => Promise, - args: Array, -): Promise<{result: mixed, parallelismHistory: Array}> { - const parallelismHistory = []; - let parralelism = 0; - const result = await asyncFunction( - ...args.map(arg => { +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));let captureParallelismHistory = (() => {var _ref34 = (0, _asyncToGenerator.default)( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + function* ( + asyncFunction, + args) + { + const parallelismHistory = []; + let parralelism = 0; + const result = yield asyncFunction( + ...args.map(function (arg) { if (typeof arg !== 'function') { return arg; } const func = arg; - return async item => { - ++parralelism; - parallelismHistory.push(parralelism); - const value = await func(item); - --parralelism; - return value; - }; - }), - ); - return {result, parallelismHistory}; -} - -function waitPromise(timeoutMs: number, value: any): Promise { - return new Promise((resolve, reject) => { - setTimeout(() => resolve(value), timeoutMs); - }); -} + return (() => {var _ref35 = (0, _asyncToGenerator.default)(function* (item) { + ++parralelism; + parallelismHistory.push(parralelism); + const value = yield func(item); + --parralelism; + return value; + });return function (_x4) {return _ref35.apply(this, arguments);};})(); + })); + + return { result, parallelismHistory }; + });return function captureParallelismHistory(_x2, _x3) {return _ref34.apply(this, arguments);};})();var _promise;function _load_promise() {return _promise = require('../promise');}var _testHelpers;function _load_testHelpers() {return _testHelpers = require('../test-helpers');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */ /* eslint-disable prefer-promise-reject-errors */describe('promises::asyncFind()', () => {it('Empty list of items should resolve to null.', () => {let isResolved = false;let observedResult;let isRejected = false;let observedError;const args = [];const test = value => {throw new Error('Should not be called.');};runs(() => {(0, (_promise || _load_promise()).asyncFind)(args, test).then(result => {observedResult = result;isResolved = true;}).catch(error => {observedError = error;isRejected = true;});});waitsFor(() => isResolved || isRejected);runs(() => {expect(isResolved).toBe(true);expect(observedResult).toBe(null);expect(isRejected).toBe(false);expect(observedError).toBe(undefined);});});it('Last item in list resolves.', () => {let isResolved = false;let observedResult;let isRejected = false;let observedError;const args = ['foo', 'bar', 'baz'];const test = value => {if (value === 'foo') {return null;} else if (value === 'bar') {return Promise.resolve(null);} else {return Promise.resolve('win');}};runs(() => {(0, (_promise || _load_promise()).asyncFind)(args, test).then(result => {observedResult = result;isResolved = true;}).catch(error => {observedError = error;isRejected = true;});});waitsFor(() => isResolved || isRejected);runs(() => {expect(isResolved).toBe(true);expect(observedResult).toBe('win');expect(isRejected).toBe(false);expect(observedError).toBe(undefined);});});});describe('promises::denodeify()', () => {/** + * Vararg function that assumes that all elements except the last are + * numbers, as the last argument is a callback function. All of the + * other arguments are multiplied together. If the result is not NaN, + * then the callback is called with the product. Otherwise, the callback + * is called with an error. + * + * This function exhibits some of the quirky behavior of Node APIs that + * accept a variable number of arguments in the middle of the parameter list + * rather than at the end. The type signature of this function cannot be + * expressed in Flow. + */function asyncProduct(...factors) {const callback = factors.pop();const product = factors.reduce((previousValue, currentValue) => {return previousValue * currentValue;}, 1);if (isNaN(product)) {callback(new Error('product was NaN'));} else {callback(null, product);}}it('resolves Promise when callback succeeds', () => {const denodeifiedAsyncProduct = (0, (_promise || _load_promise()).denodeify)(asyncProduct);waitsForPromise((0, _asyncToGenerator.default)(function* () {const trivialProduct = yield denodeifiedAsyncProduct();expect(trivialProduct).toBe(1);const product = yield denodeifiedAsyncProduct(1, 2, 3, 4, 5);expect(product).toBe(120);}));});it('rejects Promise when callback fails', () => {const denodeifiedAsyncProduct = (0, (_promise || _load_promise()).denodeify)(asyncProduct);waitsForPromise((0, _asyncToGenerator.default)(function* () {yield (0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)(denodeifiedAsyncProduct('a', 'b'), function (error) {expect(error.message).toBe('product was NaN');});}));});function checksReceiver(expectedReceiver, callback) {if (this === expectedReceiver) {callback(null, 'winner');} else {callback(new Error('unexpected receiver'));}}it('result of denodeify propagates receiver as expected', () => {const denodeifiedChecksReceiver = (0, (_promise || _load_promise()).denodeify)(checksReceiver);waitsForPromise((0, _asyncToGenerator.default)(function* () {const receiver = { denodeifiedChecksReceiver };const result = yield receiver.denodeifiedChecksReceiver(receiver);expect(result).toBe('winner');}));waitsForPromise((0, _asyncToGenerator.default)(function* () {const receiver = { denodeifiedChecksReceiver };yield (0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)(receiver.denodeifiedChecksReceiver(null), function (error) {expect(error.message).toBe('unexpected receiver');});}));});});describe('promises::serializeAsyncCall()', () => {it('Returns the same result when called after scheduled', () => {let i = 0;const asyncFunSpy = jasmine.createSpy('async');const oneAsyncCallAtATime = (0, (_promise || _load_promise()).serializeAsyncCall)(() => {i++;const resultPromise = waitPromise(10, i);asyncFunSpy();return resultPromise;}); // Start an async, and resolve to 1 in 10 ms. + const result1Promise = oneAsyncCallAtATime(); // Schedule the next async, and resolve to 2 in 20 ms. + const result2Promise = oneAsyncCallAtATime(); // Reuse scheduled promise and resolve to 2 in 20 ms. + const result3Promise = oneAsyncCallAtATime();advanceClock(11); // Wait for the promise to call the next chain + // That isn't synchrnously guranteed because it happens on `process.nextTick`. + waitsFor(() => asyncFunSpy.callCount === 2);waitsForPromise((0, _asyncToGenerator.default)(function* () {advanceClock(11);const results = yield Promise.all([result1Promise, result2Promise, result3Promise]);expect(results).toEqual([1, 2, 2]);}));});it('Calls and returns (even if errors) the same number of times if serially called', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {let i = 0;const oneAsyncCallAtATime = (0, (_promise || _load_promise()).serializeAsyncCall)(function () {i++;if (i === 4) {return Promise.reject('ERROR');}return waitPromise(10, i);});const result1Promise = oneAsyncCallAtATime();advanceClock(11);const result1 = yield result1Promise;const result2Promise = oneAsyncCallAtATime();advanceClock(11);const result2 = yield result2Promise;const result3Promise = oneAsyncCallAtATime();advanceClock(11);const result3 = yield result3Promise;const errorPromoise = oneAsyncCallAtATime();advanceClock(11);yield (0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)(errorPromoise, function (error) {expect(error).toBe('ERROR');});const result5Promise = oneAsyncCallAtATime();advanceClock(11);const result5 = yield result5Promise;expect([result1, result2, result3, result5]).toEqual([1, 2, 3, 5]);}));});});describe('promises::asyncLimit()', () => {beforeEach(() => {jasmine.useRealClock();});it('runs in series if limit is 1', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const { result, parallelismHistory } = yield captureParallelismHistory((_promise || _load_promise()).asyncLimit, [[1, 2, 3], 1, function (item) {return waitPromise(10, item + 1);}]);expect(parallelismHistory).toEqual([1, 1, 1]);expect(result).toEqual([2, 3, 4]);}));});it('runs with the specified limit, until finishing', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const { result, parallelismHistory } = yield captureParallelismHistory((_promise || _load_promise()).asyncLimit, [[1, 2, 3, 4, 5, 6, 7, 8, 9], 3, function (item) {return waitPromise(10 + item, item - 1);}]);expect(result).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8]);expect(parallelismHistory).toEqual([1, 2, 3, 3, 3, 3, 3, 3, 3]);}));});it('works when the limit is bigger than the array length', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const result = yield (0, (_promise || _load_promise()).asyncLimit)([1, 2, 3], 10, function (item) {return waitPromise(10, item * 2);});expect(result).toEqual([2, 4, 6]);}));});it('a rejected promise rejects the whole call with the error', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {yield (0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)((0, (_promise || _load_promise()).asyncLimit)([1], 1, (() => {var _ref11 = (0, _asyncToGenerator.default)(function* (item) {throw new Error('rejected iterator promise');});return function (_x) {return _ref11.apply(this, arguments);};})()), function (error) {expect(error.message).toBe('rejected iterator promise');});}));});it('works when the array is empty', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const result = yield (0, (_promise || _load_promise()).asyncLimit)([], 1, function () {return Promise.resolve();});expect(result).toEqual([]);}));});});describe('promises::asyncFilter()', () => {beforeEach(() => {jasmine.useRealClock();}); // eslint-disable-next-line max-len + it('filters an array with an async iterator and maximum parallelization when no limit is specified', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const { result: filtered, parallelismHistory } = yield captureParallelismHistory((_promise || _load_promise()).asyncFilter, [[1, 2, 3, 4, 5], function (item) {return waitPromise(10 + item, item > 2);}]);expect(filtered).toEqual([3, 4, 5]);expect(parallelismHistory).toEqual([1, 2, 3, 4, 5]);}));});it('filters an array with a limit on parallelization', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const { result: filtered, parallelismHistory } = yield captureParallelismHistory((_promise || _load_promise()).asyncFilter, [[1, 2, 3, 4, 5], function (item) {return waitPromise(10 + item, item > 2);}, 3]);expect(filtered).toEqual([3, 4, 5]); // Increasing promise resolve time will gurantee maximum parallelization. + expect(parallelismHistory).toEqual([1, 2, 3, 3, 3]);}));});});describe('promises::asyncObjFilter()', () => {beforeEach(() => {jasmine.useRealClock();}); // eslint-disable-next-line max-len + it('filters an object with an async iterator and maximum parallelization when no limit is specified', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const { result: filtered, parallelismHistory } = yield captureParallelismHistory((_promise || _load_promise()).asyncObjFilter, [{ a: 1, b: 2, c: 3, d: 4, e: 5 }, function (value, key) {return waitPromise(5 + value, value > 2);}]);expect(filtered).toEqual({ c: 3, d: 4, e: 5 });expect(parallelismHistory).toEqual([1, 2, 3, 4, 5]);}));});it('filters an array with a limit on parallelization', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const { result: filtered, parallelismHistory } = yield captureParallelismHistory((_promise || _load_promise()).asyncObjFilter, [{ a: 1, b: 2, c: 3, d: 4, e: 5 }, function (value, key) {return waitPromise(5 + value, value > 2);}, 3]);expect(filtered).toEqual({ c: 3, d: 4, e: 5 }); // Increasing promise resolve time will gurantee maximum parallelization. + expect(parallelismHistory).toEqual([1, 2, 3, 3, 3]);}));});});describe('promises::asyncSome()', () => {beforeEach(() => {jasmine.useRealClock();}); // eslint-disable-next-line max-len + it('some an array with an async iterator and maximum parallelization when no limit is specified', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const { result, parallelismHistory } = yield captureParallelismHistory((_promise || _load_promise()).asyncSome, [[1, 2, 3, 4, 5], function (item) {return waitPromise(10, item === 6);}]);expect(result).toEqual(false);expect(parallelismHistory).toEqual([1, 2, 3, 4, 5]);}));});it('some an array with a limit on parallelization', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const { result, parallelismHistory } = yield captureParallelismHistory((_promise || _load_promise()).asyncSome, [[1, 2, 3, 4, 5], function (item) {return waitPromise(10 + item, item === 5);}, 3]);expect(result).toEqual(true);expect(parallelismHistory).toEqual([1, 2, 3, 3, 3]);}));});});describe('promises::lastly', () => {it('executes after a resolved promise', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const spy = jasmine.createSpy('spy');const result = yield (0, (_promise || _load_promise()).lastly)(Promise.resolve(1), spy);expect(result).toBe(1);expect(spy).toHaveBeenCalled();}));});it('executes after a rejected promise', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const spy = jasmine.createSpy('spy');yield (0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)((0, (_promise || _load_promise()).lastly)(Promise.reject(2), spy), function (err) {expect(err).toBe(2);});expect(spy).toHaveBeenCalled();}));});it('works for async functions', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const spy = jasmine.createSpy('spy');const result = yield (0, (_promise || _load_promise()).lastly)(Promise.resolve(1), (0, _asyncToGenerator.default)(function* () {spy();}));expect(result).toBe(1);expect(spy).toHaveBeenCalled();}));});});describe('promises::retryLimit()', () => {beforeEach(() => {jasmine.useRealClock();});it('retries and fails 2 times before resolving to an acceptable result where limit = 5', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {let succeedAfter = 2;let calls = 0;let validationCalls = 0;const retrialsResult = yield (0, (_promise || _load_promise()).retryLimit)(function () {return new Promise(function (resolve, reject) {calls++;if (succeedAfter-- === 0) {resolve('RESULT');} else {reject('ERROR');}});}, function (result) {validationCalls++;return result === 'RESULT';}, 5);expect(calls).toBe(3);expect(validationCalls).toBe(1);expect(retrialsResult).toBe('RESULT');}));});it('retries and fails consistently', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {let calls = 0;let validationCalls = 0;const failRetriesPromise = (0, (_promise || _load_promise()).retryLimit)(function () {calls++;return Promise.reject('ERROR');}, function (result) {validationCalls++;return result != null;}, 2);yield (0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)(failRetriesPromise, function (error) {expect(error).toBe('ERROR');});expect(calls).toBe(2);expect(validationCalls).toBe(0);}));});it('accepts a null response', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {let succeedAfter = 2;let calls = 0;let validationCalls = 0;const retryResult = yield (0, (_promise || _load_promise()).retryLimit)(function () {calls++;if (succeedAfter-- === 0) {return Promise.resolve(null);} else {return Promise.resolve('NOT_GOOD');}}, function (result) {validationCalls++;return result == null;}, 5);expect(retryResult).toBe(null);expect(calls).toBe(3);expect(validationCalls).toBe(3);}));});it('no valid response is ever got', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const nonValidRetriesPromise = (0, (_promise || _load_promise()).retryLimit)(function () {return Promise.resolve('A');}, function (result) {return result === 'B';}, 2);yield (0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)(nonValidRetriesPromise, function (error) {expect(error.message).toBe('No valid response found!');});}));});});describe('promises::RequestSerializer()', () => {let requestSerializer = null;beforeEach(() => {jasmine.useRealClock();requestSerializer = new (_promise || _load_promise()).RequestSerializer();});it('gets outdated result for old promises resolving after newer calls', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const oldPromise = requestSerializer.run(waitPromise(10, 'OLD'));const newPromise = requestSerializer.run(waitPromise(5, 'NEW'));const { status: oldStatus } = yield oldPromise;expect(oldStatus).toBe('outdated');const newResult = yield newPromise;if (!(newResult.status === 'success')) {throw new Error('Invariant violation: "newResult.status === \'success\'"');}expect(newResult.result).toBe('NEW');}));});it('waitForLatestResult: waits for the latest result', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {requestSerializer.run(waitPromise(5, 'OLD'));requestSerializer.run(waitPromise(10, 'NEW'));const latestResult = yield requestSerializer.waitForLatestResult();expect(latestResult).toBe('NEW');}));});it('waitForLatestResult: waits even if the first run did not kick off', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const latestResultPromise = requestSerializer.waitForLatestResult();requestSerializer.run(waitPromise(10, 'RESULT'));const latestResult = yield latestResultPromise;expect(latestResult).toBe('RESULT');}));});it('waitForLatestResult: does not wait for the first, if the second resolves faster', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {requestSerializer.run(waitPromise(1000000, 'OLD')); // This will never resolve. + requestSerializer.run(waitPromise(10, 'NEW'));const latestResult = yield requestSerializer.waitForLatestResult();expect(latestResult).toBe('NEW');}));});});describe('timeoutPromise', () => {it('should resolve normally if within the timeout', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const inputPromise = new Promise(function (resolve) {return resolve('foo');});const outputPromise = (0, (_promise || _load_promise()).timeoutPromise)(inputPromise, 1000);expect((yield outputPromise)).toBe('foo');}));});it('should reject if the given promise rejects', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const inputPromise = new Promise(function (resolve, reject) {return reject('foo');});const outputPromise = (0, (_promise || _load_promise()).timeoutPromise)(inputPromise, 1000).catch(function (value) {return `rejected with ${value}`;});expect((yield outputPromise)).toBe('rejected with foo');}));});it('should reject if the given promise takes too long', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const inputPromise = new Promise(function (resolve) {return setTimeout(resolve, 2000);});const outputPromise = (0, (_promise || _load_promise()).timeoutPromise)(inputPromise, 1000).catch(function (value) {return value;});advanceClock(1500);expect((yield outputPromise)).toEqual(new (_promise || _load_promise()).TimedOutError(1000));}));});});function waitPromise(timeoutMs, value) {return new Promise((resolve, reject) => {setTimeout(() => resolve(value), timeoutMs);});} \ No newline at end of file diff --git a/modules/nuclide-commons/spec/range-spec.js b/modules/nuclide-commons/spec/range-spec.js index e2cef1f7..b0889846 100644 --- a/modules/nuclide-commons/spec/range-spec.js +++ b/modules/nuclide-commons/spec/range-spec.js @@ -1,33 +1,43 @@ -/** - * 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 - * @format - */ - -import invariant from 'assert'; -import {default as TextBuffer, Range} from 'simple-text-buffer'; -import {wordAtPositionFromBuffer} from '../range'; +'use strict';var _simpleTextBuffer; + + + + + + + + + + + + +function _load_simpleTextBuffer() {return _simpleTextBuffer = _interopRequireDefault(require('simple-text-buffer'));}var _simpleTextBuffer2;function _load_simpleTextBuffer2() {return _simpleTextBuffer2 = require('simple-text-buffer');}var _range; +function _load_range() {return _range = require('../range');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} describe('wordAtPositionFromBuffer', () => { it('matches a word in a buffer', () => { - const buffer = new TextBuffer('word1 word2 word3\n'); - const match = wordAtPositionFromBuffer(buffer, {row: 0, column: 6}, /\S+/g); - expect(match).not.toBeNull(); - invariant(match != null); + const buffer = new (_simpleTextBuffer || _load_simpleTextBuffer()).default('word1 word2 word3\n'); + const match = (0, (_range || _load_range()).wordAtPositionFromBuffer)(buffer, { row: 0, column: 6 }, /\S+/g); + expect(match).not.toBeNull();if (!( + match != null)) {throw new Error('Invariant violation: "match != null"');} expect(match.wordMatch.length).toBe(1); expect(match.wordMatch[0]).toBe('word2'); - expect(match.range).toEqual(new Range([0, 6], [0, 11])); + expect(match.range).toEqual(new (_simpleTextBuffer2 || _load_simpleTextBuffer2()).Range([0, 6], [0, 11])); }); it('should not include endpoints', () => { - const buffer = new TextBuffer('word1 word2 word3\n'); - const match = wordAtPositionFromBuffer(buffer, {row: 0, column: 5}, /\S+/g); + const buffer = new (_simpleTextBuffer || _load_simpleTextBuffer()).default('word1 word2 word3\n'); + const match = (0, (_range || _load_range()).wordAtPositionFromBuffer)(buffer, { row: 0, column: 5 }, /\S+/g); expect(match).toBeNull(); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/spec/shell-quote-spec.js b/modules/nuclide-commons/spec/shell-quote-spec.js index f542088c..aba8dd09 100644 --- a/modules/nuclide-commons/spec/shell-quote-spec.js +++ b/modules/nuclide-commons/spec/shell-quote-spec.js @@ -1,42 +1,52 @@ -/** - * 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 - * @format - */ - -import {parse, quote} from '../_shell-quote'; +'use strict';var _shellQuote; + + + + + + + + + + + +function _load_shellQuote() {return _shellQuote = require('../_shell-quote');} /** - * The rest of shell-quote has been verified to work correctly. - * We just need to test the comment parsing. - */ + * The rest of shell-quote has been verified to work correctly. + * We just need to test the comment parsing. + */ describe('shell-quote', () => { describe('parse', () => { it('parses comments correctly', () => { - expect(parse('beep#boop')).toEqual(['beep#boop']); - expect(parse('beep #boop')).toEqual(['beep', {comment: 'boop'}]); - expect(parse('beep # boop')).toEqual(['beep', {comment: 'boop'}]); - expect(parse('beep # > boop')).toEqual(['beep', {comment: '> boop'}]); - expect(parse('beep # "> boop"')).toEqual(['beep', {comment: '"> boop"'}]); - expect(parse('beep "#"')).toEqual(['beep', '#']); - expect(parse('beep #"#"#')).toEqual(['beep', {comment: '"#"#'}]); - expect(parse('beep > boop # > foo')).toEqual([ - 'beep', - {op: '>'}, - 'boop', - {comment: '> foo'}, - ]); + expect((0, (_shellQuote || _load_shellQuote()).parse)('beep#boop')).toEqual(['beep#boop']); + expect((0, (_shellQuote || _load_shellQuote()).parse)('beep #boop')).toEqual(['beep', { comment: 'boop' }]); + expect((0, (_shellQuote || _load_shellQuote()).parse)('beep # boop')).toEqual(['beep', { comment: 'boop' }]); + expect((0, (_shellQuote || _load_shellQuote()).parse)('beep # > boop')).toEqual(['beep', { comment: '> boop' }]); + expect((0, (_shellQuote || _load_shellQuote()).parse)('beep # "> boop"')).toEqual(['beep', { comment: '"> boop"' }]); + expect((0, (_shellQuote || _load_shellQuote()).parse)('beep "#"')).toEqual(['beep', '#']); + expect((0, (_shellQuote || _load_shellQuote()).parse)('beep #"#"#')).toEqual(['beep', { comment: '"#"#' }]); + expect((0, (_shellQuote || _load_shellQuote()).parse)('beep > boop # > foo')).toEqual([ + 'beep', + { op: '>' }, + 'boop', + { comment: '> foo' }]); + }); }); describe('quote', () => { - expect(quote(['X#(){}*|][!'])).toBe('X\\#\\(\\)\\{\\}\\*\\|\\]\\[\\!'); + expect((0, (_shellQuote || _load_shellQuote()).quote)(['X#(){}*|][!'])).toBe('X\\#\\(\\)\\{\\}\\*\\|\\]\\[\\!'); }); -}); +}); /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-commons/spec/stream-spec.js b/modules/nuclide-commons/spec/stream-spec.js index f6eb3a5f..b548daba 100644 --- a/modules/nuclide-commons/spec/stream-spec.js +++ b/modules/nuclide-commons/spec/stream-spec.js @@ -1,77 +1,77 @@ -/** - * 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 - * @format - */ - -import {observeStream, observeRawStream, writeToStream} from '../stream'; -import fsPromise from '../fsPromise'; -import Stream from 'stream'; -import fs from 'fs'; - -describe('commons-node/stream', () => { - it('observeStream', () => { - waitsForPromise(async () => { - const input = ['foo\nbar', '\n', '\nba', 'z', '\nblar']; - const stream = new Stream.PassThrough(); - const promise = observeStream(stream) - .toArray() - .toPromise(); - input.forEach(value => { +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _stream; + + + + + + + + + + + +function _load_stream() {return _stream = require('../stream');}var _fsPromise; +function _load_fsPromise() {return _fsPromise = _interopRequireDefault(require('../fsPromise'));} +var _stream2 = _interopRequireDefault(require('stream')); +var _fs = _interopRequireDefault(require('fs'));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */describe('commons-node/stream', () => {it('observeStream', () => {waitsForPromise((0, _asyncToGenerator.default)(function* () {const input = ['foo\nbar', '\n', '\nba', 'z', '\nblar'];const stream = new _stream2.default.PassThrough();const promise = (0, (_stream || _load_stream()).observeStream)(stream).toArray().toPromise();input.forEach(function (value) { stream.write(value, 'utf8'); }); stream.end(); - const output = await promise; + const output = yield promise; expect(output.join('')).toEqual(input.join('')); - }); + })); }); it('observeStream - error', () => { - waitsForPromise(async () => { - const stream = new Stream.PassThrough(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const stream = new _stream2.default.PassThrough(); const input = ['foo\nbar', '\n', '\nba', 'z', '\nblar']; const output = []; - const promise = new Promise((resolve, reject) => { - observeStream(stream).subscribe( - v => output.push(v), - e => resolve(e), - () => {}, - ); + const promise = new Promise(function (resolve, reject) { + (0, (_stream || _load_stream()).observeStream)(stream).subscribe( + function (v) {return output.push(v);}, + function (e) {return resolve(e);}, + function () {}); + }); const error = new Error('Had an error'); - input.forEach(value => { + input.forEach(function (value) { stream.write(value, 'utf8'); }); stream.emit('error', error); - const result = await promise; + const result = yield promise; expect(output).toEqual(input); expect(result).toBe(error); - }); + })); }); it('writeToStream', () => { - waitsForPromise(async () => { - const tempPath = await fsPromise.tempfile(); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const tempPath = yield (_fsPromise || _load_fsPromise()).default.tempfile(); const fixturePath = 'spec/fixtures/lyrics'; - const stream = fs.createWriteStream(tempPath, {highWaterMark: 10}); + const stream = _fs.default.createWriteStream(tempPath, { highWaterMark: 10 }); // Read faster than we write to test buffering - const observable = observeRawStream( - fs.createReadStream(fixturePath, {highWaterMark: 100}), - ); + const observable = (0, (_stream || _load_stream()).observeRawStream)( + _fs.default.createReadStream(fixturePath, { highWaterMark: 100 })); + - await writeToStream(observable, stream).toPromise(); + yield (0, (_stream || _load_stream()).writeToStream)(observable, stream).toPromise(); - const writtenFile = await fsPromise.readFile(tempPath); - const fixtureFile = await fsPromise.readFile(fixturePath); + const writtenFile = yield (_fsPromise || _load_fsPromise()).default.readFile(tempPath); + const fixtureFile = yield (_fsPromise || _load_fsPromise()).default.readFile(fixturePath); expect(writtenFile).toEqual(fixtureFile); - }); + })); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/spec/string-spec.js b/modules/nuclide-commons/spec/string-spec.js index 10ccdedc..98cb24b2 100644 --- a/modules/nuclide-commons/spec/string-spec.js +++ b/modules/nuclide-commons/spec/string-spec.js @@ -1,29 +1,29 @@ -/** - * 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 - * @format - */ - -import { - capitalize, - countOccurrences, - getMatchRanges, - indent, - maybeToString, - pluralize, - relativeDate, - removeCommonPrefix, - removeCommonSuffix, - shellParse, - shorten, - splitOnce, -} from '../string'; +'use strict';var _string; + + + + + + + + + + + +function _load_string() {return _string = require('../string');} + + + + + + + + + + + + + describe('relativeDate', () => { it('works', () => { @@ -39,267 +39,267 @@ describe('relativeDate', () => { const now = new Date().getTime(); // test long format - expect(relativeDate(0)).toEqual(Math.round(now / YEAR) + ' years ago'); - expect(relativeDate(reference * SECOND, reference)).toEqual('just now'); - expect(relativeDate(reference - 41 * SECOND, reference)).toEqual( - 'just now', - ); - expect(relativeDate(reference - 42 * SECOND, reference)).toEqual( - 'a minute ago', - ); - expect(relativeDate(reference - MINUTE, reference)).toEqual('a minute ago'); - expect(relativeDate(reference - MINUTE * 1.5, reference)).toEqual( - '2 minutes ago', - ); - expect(relativeDate(reference - MINUTE * 59, reference)).toEqual( - '59 minutes ago', - ); - expect(relativeDate(reference - HOUR, reference)).toEqual('an hour ago'); - expect(relativeDate(reference - HOUR * 1.5, reference)).toEqual( - '2 hours ago', - ); - expect(relativeDate(reference - HOUR * 16, reference)).toEqual( - '16 hours ago', - ); - expect(relativeDate(reference - HOUR * 23, reference)).toEqual( - '23 hours ago', - ); - expect(relativeDate(reference - DAY * 1.8, reference)).toEqual('yesterday'); - expect(relativeDate(reference - DAY * 3, reference)).toEqual('3 days ago'); - expect(relativeDate(reference - DAY * 6, reference)).toEqual('6 days ago'); - expect(relativeDate(reference - WEEK, reference)).toEqual('a week ago'); - expect(relativeDate(reference - WEEK * 2, reference)).toEqual( - '2 weeks ago', - ); - expect(relativeDate(reference - WEEK * 4, reference)).toEqual( - '4 weeks ago', - ); - expect(relativeDate(reference - MONTH * 1.2, reference)).toEqual( - 'a month ago', - ); - expect(relativeDate(reference - YEAR + HOUR, reference)).toEqual( - '12 months ago', - ); - expect(relativeDate(reference - YEAR, reference)).toEqual('a year ago'); - expect(relativeDate(reference - YEAR * 2, reference)).toEqual( - '2 years ago', - ); - expect(relativeDate(0, reference)).toEqual('5 years ago'); + expect((0, (_string || _load_string()).relativeDate)(0)).toEqual(Math.round(now / YEAR) + ' years ago'); + expect((0, (_string || _load_string()).relativeDate)(reference * SECOND, reference)).toEqual('just now'); + expect((0, (_string || _load_string()).relativeDate)(reference - 41 * SECOND, reference)).toEqual( + 'just now'); + + expect((0, (_string || _load_string()).relativeDate)(reference - 42 * SECOND, reference)).toEqual( + 'a minute ago'); + + expect((0, (_string || _load_string()).relativeDate)(reference - MINUTE, reference)).toEqual('a minute ago'); + expect((0, (_string || _load_string()).relativeDate)(reference - MINUTE * 1.5, reference)).toEqual( + '2 minutes ago'); + + expect((0, (_string || _load_string()).relativeDate)(reference - MINUTE * 59, reference)).toEqual( + '59 minutes ago'); + + expect((0, (_string || _load_string()).relativeDate)(reference - HOUR, reference)).toEqual('an hour ago'); + expect((0, (_string || _load_string()).relativeDate)(reference - HOUR * 1.5, reference)).toEqual( + '2 hours ago'); + + expect((0, (_string || _load_string()).relativeDate)(reference - HOUR * 16, reference)).toEqual( + '16 hours ago'); + + expect((0, (_string || _load_string()).relativeDate)(reference - HOUR * 23, reference)).toEqual( + '23 hours ago'); + + expect((0, (_string || _load_string()).relativeDate)(reference - DAY * 1.8, reference)).toEqual('yesterday'); + expect((0, (_string || _load_string()).relativeDate)(reference - DAY * 3, reference)).toEqual('3 days ago'); + expect((0, (_string || _load_string()).relativeDate)(reference - DAY * 6, reference)).toEqual('6 days ago'); + expect((0, (_string || _load_string()).relativeDate)(reference - WEEK, reference)).toEqual('a week ago'); + expect((0, (_string || _load_string()).relativeDate)(reference - WEEK * 2, reference)).toEqual( + '2 weeks ago'); + + expect((0, (_string || _load_string()).relativeDate)(reference - WEEK * 4, reference)).toEqual( + '4 weeks ago'); + + expect((0, (_string || _load_string()).relativeDate)(reference - MONTH * 1.2, reference)).toEqual( + 'a month ago'); + + expect((0, (_string || _load_string()).relativeDate)(reference - YEAR + HOUR, reference)).toEqual( + '12 months ago'); + + expect((0, (_string || _load_string()).relativeDate)(reference - YEAR, reference)).toEqual('a year ago'); + expect((0, (_string || _load_string()).relativeDate)(reference - YEAR * 2, reference)).toEqual( + '2 years ago'); + + expect((0, (_string || _load_string()).relativeDate)(0, reference)).toEqual('5 years ago'); // test short format - expect(relativeDate(0, undefined, /* short */ true)).toEqual( - Math.round(now / YEAR) + 'y', - ); - expect( - relativeDate(reference * SECOND, reference, /* short */ true), - ).toEqual('now'); + expect((0, (_string || _load_string()).relativeDate)(0, undefined, /* short */true)).toEqual( + Math.round(now / YEAR) + 'y'); + expect( - relativeDate(reference - 41 * SECOND, reference, /* short */ true), - ).toEqual('now'); + (0, (_string || _load_string()).relativeDate)(reference * SECOND, reference, /* short */true)). + toEqual('now'); expect( - relativeDate(reference - 42 * SECOND, reference, /* short */ true), - ).toEqual('1m'); + (0, (_string || _load_string()).relativeDate)(reference - 41 * SECOND, reference, /* short */true)). + toEqual('now'); expect( - relativeDate(reference - MINUTE, reference, /* short */ true), - ).toEqual('1m'); + (0, (_string || _load_string()).relativeDate)(reference - 42 * SECOND, reference, /* short */true)). + toEqual('1m'); expect( - relativeDate(reference - MINUTE * 1.5, reference, /* short */ true), - ).toEqual('2m'); + (0, (_string || _load_string()).relativeDate)(reference - MINUTE, reference, /* short */true)). + toEqual('1m'); expect( - relativeDate(reference - MINUTE * 59, reference, /* short */ true), - ).toEqual('59m'); - expect(relativeDate(reference - HOUR, reference, /* short */ true)).toEqual( - '1h', - ); + (0, (_string || _load_string()).relativeDate)(reference - MINUTE * 1.5, reference, /* short */true)). + toEqual('2m'); expect( - relativeDate(reference - HOUR * 1.5, reference, /* short */ true), - ).toEqual('2h'); + (0, (_string || _load_string()).relativeDate)(reference - MINUTE * 59, reference, /* short */true)). + toEqual('59m'); + expect((0, (_string || _load_string()).relativeDate)(reference - HOUR, reference, /* short */true)).toEqual( + '1h'); + expect( - relativeDate(reference - HOUR * 16, reference, /* short */ true), - ).toEqual('16h'); + (0, (_string || _load_string()).relativeDate)(reference - HOUR * 1.5, reference, /* short */true)). + toEqual('2h'); expect( - relativeDate(reference - HOUR * 23, reference, /* short */ true), - ).toEqual('23h'); + (0, (_string || _load_string()).relativeDate)(reference - HOUR * 16, reference, /* short */true)). + toEqual('16h'); expect( - relativeDate(reference - DAY * 1.8, reference, /* short */ true), - ).toEqual('1d'); + (0, (_string || _load_string()).relativeDate)(reference - HOUR * 23, reference, /* short */true)). + toEqual('23h'); expect( - relativeDate(reference - DAY * 3, reference, /* short */ true), - ).toEqual('3d'); + (0, (_string || _load_string()).relativeDate)(reference - DAY * 1.8, reference, /* short */true)). + toEqual('1d'); expect( - relativeDate(reference - DAY * 6, reference, /* short */ true), - ).toEqual('6d'); - expect(relativeDate(reference - WEEK, reference, /* short */ true)).toEqual( - '1w', - ); + (0, (_string || _load_string()).relativeDate)(reference - DAY * 3, reference, /* short */true)). + toEqual('3d'); expect( - relativeDate(reference - WEEK * 2, reference, /* short */ true), - ).toEqual('2w'); + (0, (_string || _load_string()).relativeDate)(reference - DAY * 6, reference, /* short */true)). + toEqual('6d'); + expect((0, (_string || _load_string()).relativeDate)(reference - WEEK, reference, /* short */true)).toEqual( + '1w'); + expect( - relativeDate(reference - WEEK * 4, reference, /* short */ true), - ).toEqual('4w'); + (0, (_string || _load_string()).relativeDate)(reference - WEEK * 2, reference, /* short */true)). + toEqual('2w'); expect( - relativeDate(reference - MONTH * 1.2, reference, /* short */ true), - ).toEqual('1mo'); + (0, (_string || _load_string()).relativeDate)(reference - WEEK * 4, reference, /* short */true)). + toEqual('4w'); expect( - relativeDate(reference - YEAR + HOUR, reference, /* short */ true), - ).toEqual('12mo'); - expect(relativeDate(reference - YEAR, reference, /* short */ true)).toEqual( - '1y', - ); + (0, (_string || _load_string()).relativeDate)(reference - MONTH * 1.2, reference, /* short */true)). + toEqual('1mo'); expect( - relativeDate(reference - YEAR * 2, reference, /* short */ true), - ).toEqual('2y'); - expect(relativeDate(0, reference, /* short */ true)).toEqual('5y'); - }); -}); + (0, (_string || _load_string()).relativeDate)(reference - YEAR + HOUR, reference, /* short */true)). + toEqual('12mo'); + expect((0, (_string || _load_string()).relativeDate)(reference - YEAR, reference, /* short */true)).toEqual( + '1y'); -describe('maybeToString', () => { - it("returns 'undefined'", () => { - expect(maybeToString(undefined)).toEqual('undefined'); - }); - - it("returns 'null'", () => { - expect(maybeToString(null)).toEqual('null'); + expect( + (0, (_string || _load_string()).relativeDate)(reference - YEAR * 2, reference, /* short */true)). + toEqual('2y'); + expect((0, (_string || _load_string()).relativeDate)(0, reference, /* short */true)).toEqual('5y'); }); - +}); /** + * 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. + * + * + * @format + */describe('maybeToString', () => {it("returns 'undefined'", () => {expect((0, (_string || _load_string()).maybeToString)(undefined)).toEqual('undefined');});it("returns 'null'", () => {expect((0, (_string || _load_string()).maybeToString)(null)).toEqual('null');}); it('returns an ordinary string', () => { - expect(maybeToString('foo')).toEqual('foo'); + expect((0, (_string || _load_string()).maybeToString)('foo')).toEqual('foo'); }); }); describe('countOccurrences', () => { it('counts the number of characters', () => { - expect(countOccurrences('abcaaa', 'a')).toBe(4); + expect((0, (_string || _load_string()).countOccurrences)('abcaaa', 'a')).toBe(4); }); it('throws for non-length-1 searches', () => { expect(() => { - countOccurrences('abc', 'abc'); + (0, (_string || _load_string()).countOccurrences)('abc', 'abc'); }).toThrow(); }); }); describe('shellParse', () => { it('parses a list of arguments', () => { - expect(shellParse('1 2 3 "a b c"')).toEqual(['1', '2', '3', 'a b c']); + expect((0, (_string || _load_string()).shellParse)('1 2 3 "a b c"')).toEqual(['1', '2', '3', 'a b c']); }); it('throws if operators are given', () => { expect(() => { - shellParse('a | b'); + (0, (_string || _load_string()).shellParse)('a | b'); }).toThrow(Error('Unexpected operator "|" provided to shellParse')); expect(() => { - shellParse('a > b'); + (0, (_string || _load_string()).shellParse)('a > b'); }).toThrow(Error('Unexpected operator ">" provided to shellParse')); }); }); describe('removeCommonPrefix', () => { it('does nothing if there is no common prefix', () => { - expect(removeCommonPrefix('foo', 'bar')).toEqual(['foo', 'bar']); + expect((0, (_string || _load_string()).removeCommonPrefix)('foo', 'bar')).toEqual(['foo', 'bar']); }); it('removes a common prefix', () => { - expect(removeCommonPrefix('foo', 'fbar')).toEqual(['oo', 'bar']); - expect(removeCommonPrefix('asdffoo', 'asdfbar')).toEqual(['foo', 'bar']); + expect((0, (_string || _load_string()).removeCommonPrefix)('foo', 'fbar')).toEqual(['oo', 'bar']); + expect((0, (_string || _load_string()).removeCommonPrefix)('asdffoo', 'asdfbar')).toEqual(['foo', 'bar']); }); it('works with the empty string', () => { - expect(removeCommonPrefix('', 'bar')).toEqual(['', 'bar']); - expect(removeCommonPrefix('foo', '')).toEqual(['foo', '']); - expect(removeCommonPrefix('', '')).toEqual(['', '']); + expect((0, (_string || _load_string()).removeCommonPrefix)('', 'bar')).toEqual(['', 'bar']); + expect((0, (_string || _load_string()).removeCommonPrefix)('foo', '')).toEqual(['foo', '']); + expect((0, (_string || _load_string()).removeCommonPrefix)('', '')).toEqual(['', '']); }); it('returns empty strings for identical strings', () => { - expect(removeCommonPrefix('foo', 'foo')).toEqual(['', '']); + expect((0, (_string || _load_string()).removeCommonPrefix)('foo', 'foo')).toEqual(['', '']); }); }); describe('removeCommonSuffix', () => { it('does nothing if there is no common suffix', () => { - expect(removeCommonSuffix('foo', 'bar')).toEqual(['foo', 'bar']); + expect((0, (_string || _load_string()).removeCommonSuffix)('foo', 'bar')).toEqual(['foo', 'bar']); }); it('removes a common suffix', () => { - expect(removeCommonSuffix('foo', 'baro')).toEqual(['fo', 'bar']); - expect(removeCommonSuffix('fooasdf', 'baroasdf')).toEqual(['fo', 'bar']); + expect((0, (_string || _load_string()).removeCommonSuffix)('foo', 'baro')).toEqual(['fo', 'bar']); + expect((0, (_string || _load_string()).removeCommonSuffix)('fooasdf', 'baroasdf')).toEqual(['fo', 'bar']); }); it('works with the empty string', () => { - expect(removeCommonSuffix('', 'bar')).toEqual(['', 'bar']); - expect(removeCommonSuffix('foo', '')).toEqual(['foo', '']); - expect(removeCommonSuffix('', '')).toEqual(['', '']); + expect((0, (_string || _load_string()).removeCommonSuffix)('', 'bar')).toEqual(['', 'bar']); + expect((0, (_string || _load_string()).removeCommonSuffix)('foo', '')).toEqual(['foo', '']); + expect((0, (_string || _load_string()).removeCommonSuffix)('', '')).toEqual(['', '']); }); it('returns empty strings for identical strings', () => { - expect(removeCommonSuffix('foo', 'foo')).toEqual(['', '']); + expect((0, (_string || _load_string()).removeCommonSuffix)('foo', 'foo')).toEqual(['', '']); }); }); describe('shorten', () => { it('works', () => { - expect(shorten('', 1)).toEqual(''); - expect(shorten('test', 3)).toEqual('tes'); - expect(shorten('test', 100)).toEqual('test'); - expect(shorten('test', 1, '...')).toEqual('t...'); + expect((0, (_string || _load_string()).shorten)('', 1)).toEqual(''); + expect((0, (_string || _load_string()).shorten)('test', 3)).toEqual('tes'); + expect((0, (_string || _load_string()).shorten)('test', 100)).toEqual('test'); + expect((0, (_string || _load_string()).shorten)('test', 1, '...')).toEqual('t...'); }); }); describe('splitOnce', () => { it('splits once', () => { - expect(splitOnce('ab-cd-ef', '-')).toEqual(['ab', 'cd-ef']); + expect((0, (_string || _load_string()).splitOnce)('ab-cd-ef', '-')).toEqual(['ab', 'cd-ef']); }); it("handles when there's no match", () => { - expect(splitOnce('ab-cd-ef', '_')).toEqual(['ab-cd-ef', null]); + expect((0, (_string || _load_string()).splitOnce)('ab-cd-ef', '_')).toEqual(['ab-cd-ef', null]); }); }); describe('indent', () => { it('indents lines', () => { - expect(indent('a\nb')).toBe(' a\n b'); + expect((0, (_string || _load_string()).indent)('a\nb')).toBe(' a\n b'); }); it("doesn't indent empty lines", () => { - expect(indent('a\n\nb')).toBe(' a\n\n b'); + expect((0, (_string || _load_string()).indent)('a\n\nb')).toBe(' a\n\n b'); }); it('uses the provided level', () => { - expect(indent('a\n\nb', 4)).toBe(' a\n\n b'); + expect((0, (_string || _load_string()).indent)('a\n\nb', 4)).toBe(' a\n\n b'); }); it('uses the provided character', () => { - expect(indent('a\n\nb', 1, '\t')).toBe('\ta\n\n\tb'); + expect((0, (_string || _load_string()).indent)('a\n\nb', 1, '\t')).toBe('\ta\n\n\tb'); }); }); describe('pluralize', () => { it('works', () => { - expect(pluralize('test', 0)).toEqual('tests'); - expect(pluralize('test', 1)).toEqual('test'); - expect(pluralize('test', 2)).toEqual('tests'); - expect(pluralize('test', 123)).toEqual('tests'); + expect((0, (_string || _load_string()).pluralize)('test', 0)).toEqual('tests'); + expect((0, (_string || _load_string()).pluralize)('test', 1)).toEqual('test'); + expect((0, (_string || _load_string()).pluralize)('test', 2)).toEqual('tests'); + expect((0, (_string || _load_string()).pluralize)('test', 123)).toEqual('tests'); }); }); describe('capitalize', () => { it('works', () => { - expect(capitalize('')).toEqual(''); - expect(capitalize('t')).toEqual('T'); - expect(capitalize('te')).toEqual('Te'); - expect(capitalize('test')).toEqual('Test'); + expect((0, (_string || _load_string()).capitalize)('')).toEqual(''); + expect((0, (_string || _load_string()).capitalize)('t')).toEqual('T'); + expect((0, (_string || _load_string()).capitalize)('te')).toEqual('Te'); + expect((0, (_string || _load_string()).capitalize)('test')).toEqual('Test'); }); }); describe('getMatchRanges', () => { it('works', () => { - expect(getMatchRanges('test1test2test3', 'test')).toEqual([ - [0, 4], - [5, 9], - [10, 14], - ]); - expect(getMatchRanges('ttttttt', 'ttt')).toEqual([[0, 6]]); - expect(getMatchRanges('test1test2test3', 'none')).toEqual([]); - expect(getMatchRanges('test1test2test3', '')).toEqual([]); + expect((0, (_string || _load_string()).getMatchRanges)('test1test2test3', 'test')).toEqual([ + [0, 4], + [5, 9], + [10, 14]]); + + expect((0, (_string || _load_string()).getMatchRanges)('ttttttt', 'ttt')).toEqual([[0, 6]]); + expect((0, (_string || _load_string()).getMatchRanges)('test1test2test3', 'none')).toEqual([]); + expect((0, (_string || _load_string()).getMatchRanges)('test1test2test3', '')).toEqual([]); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/spec/symbol-definition-preview-spec.js b/modules/nuclide-commons/spec/symbol-definition-preview-spec.js index 6635046b..915fac07 100644 --- a/modules/nuclide-commons/spec/symbol-definition-preview-spec.js +++ b/modules/nuclide-commons/spec/symbol-definition-preview-spec.js @@ -1,203 +1,203 @@ -/** - * 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 - * @format - */ - -import nuclideUri from '../nuclideUri'; -import dedent from 'dedent'; -import {Point} from 'simple-text-buffer'; -import {getDefinitionPreview} from '../symbol-definition-preview'; -import invariant from 'assert'; - -function javascriptFixtureDefinitionWithPoint(point: Point) { - return { - path: nuclideUri.join( - __dirname, - 'fixtures', - 'symbol-definition-preview-sample.js', - ), - language: 'javascript', - position: point, - }; +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _nuclideUri; + + + + + + + + + + + +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('../nuclideUri'));}var _dedent; +function _load_dedent() {return _dedent = _interopRequireDefault(require('dedent'));}var _simpleTextBuffer; +function _load_simpleTextBuffer() {return _simpleTextBuffer = require('simple-text-buffer');}var _symbolDefinitionPreview; +function _load_symbolDefinitionPreview() {return _symbolDefinitionPreview = require('../symbol-definition-preview');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */function javascriptFixtureDefinitionWithPoint(point) {return { path: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, 'fixtures', 'symbol-definition-preview-sample.js'), language: 'javascript', + position: point }; + } -function pythonFixtureDefinitionWithPoint(point: Point) { +function pythonFixtureDefinitionWithPoint(point) { return { - path: nuclideUri.join( - __dirname, - 'fixtures', - 'symbol-definition-preview-sample.py', - ), + path: (_nuclideUri || _load_nuclideUri()).default.join( + __dirname, + 'fixtures', + 'symbol-definition-preview-sample.py'), + language: 'python', - position: point, - }; + position: point }; + } describe('getDefinitionPreview', () => { describe('Constant symbols', () => { it('returns the only line of a one-line symbol', () => { - waitsForPromise(async () => { - const preview = await getDefinitionPreview( - javascriptFixtureDefinitionWithPoint(new Point(11, 6)), - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const preview = yield (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)( + javascriptFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(11, 6))); + - expect(preview).not.toBeNull(); - invariant(preview != null); + expect(preview).not.toBeNull();if (!( + preview != null)) {throw new Error('Invariant violation: "preview != null"');} expect(preview.contents).toEqual('const A_CONSTANT = 42;'); - }); + })); }); it('returns the entire multi-line symbol', () => { - waitsForPromise(async () => { - const preview = await getDefinitionPreview( - javascriptFixtureDefinitionWithPoint(new Point(15, 6)), - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const preview = yield (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)( + javascriptFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(15, 6))); - expect(preview).not.toBeNull(); - invariant(preview != null); + + expect(preview).not.toBeNull();if (!( + preview != null)) {throw new Error('Invariant violation: "preview != null"');} expect(preview.contents).toEqual( - dedent`const A_MULTILINE_CONST = \` + (_dedent || _load_dedent()).default`const A_MULTILINE_CONST = \` hey look I span multiple lines - \`;`, - ); - }); + \`;`); + + })); }); }); describe('Type symbols', () => { it('returns an entire multi-line type', () => { - waitsForPromise(async () => { - const preview = await getDefinitionPreview( - javascriptFixtureDefinitionWithPoint(new Point(21, 5)), - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const preview = yield (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)( + javascriptFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(21, 5))); - expect(preview).not.toBeNull(); - invariant(preview != null); + + expect(preview).not.toBeNull();if (!( + preview != null)) {throw new Error('Invariant violation: "preview != null"');} expect(preview.contents).toEqual( - dedent`type Something = { + (_dedent || _load_dedent()).default`type Something = { name: string, age?: number, - };`, - ); - }); + };`); + + })); }); it('returns only the property from within a type', () => { - waitsForPromise(async () => { - const preview = await getDefinitionPreview( - javascriptFixtureDefinitionWithPoint(new Point(44, 4)), - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const preview = yield (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)( + javascriptFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(44, 4))); - expect(preview).not.toBeNull(); - invariant(preview != null); + + expect(preview).not.toBeNull();if (!( + preview != null)) {throw new Error('Invariant violation: "preview != null"');} expect(preview.contents).toEqual('name: string,'); - }); + })); }); it('returns property and value of a complex type within a type', () => { - waitsForPromise(async () => { - const preview = await getDefinitionPreview( - javascriptFixtureDefinitionWithPoint(new Point(43, 2)), - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const preview = yield (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)( + javascriptFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(43, 2))); + - expect(preview).not.toBeNull(); - invariant(preview != null); + expect(preview).not.toBeNull();if (!( + preview != null)) {throw new Error('Invariant violation: "preview != null"');} expect(preview.contents).toEqual( - dedent`properties: { + (_dedent || _load_dedent()).default`properties: { name: string, age?: number, - },`, - ); - }); + },`); + + })); }); }); describe('Function symbols', () => { it('returns just one line if parens are balanced on the first line', () => { - waitsForPromise(async () => { - const preview = await getDefinitionPreview( - javascriptFixtureDefinitionWithPoint(new Point(26, 16)), - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const preview = yield (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)( + javascriptFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(26, 16))); + - expect(preview).not.toBeNull(); - invariant(preview != null); + expect(preview).not.toBeNull();if (!( + preview != null)) {throw new Error('Invariant violation: "preview != null"');} expect(preview.contents).toEqual( - 'export function aSingleLineFunctionSignature() {', - ); - }); + 'export function aSingleLineFunctionSignature() {'); + + })); }); it('works without parentheses as with python', () => { - waitsForPromise(async () => { - const preview = await getDefinitionPreview( - pythonFixtureDefinitionWithPoint(new Point(7, 4)), - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const preview = yield (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)( + pythonFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(7, 4))); + - expect(preview).not.toBeNull(); - invariant(preview != null); + expect(preview).not.toBeNull();if (!( + preview != null)) {throw new Error('Invariant violation: "preview != null"');} expect(preview.contents).toEqual('def foo(bar=27):'); - }); + })); }); it('works without parentheses but with braces as with python', () => { - waitsForPromise(async () => { - const preview = await getDefinitionPreview( - pythonFixtureDefinitionWithPoint(new Point(11, 4)), - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const preview = yield (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)( + pythonFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(11, 4))); - expect(preview).not.toBeNull(); - invariant(preview != null); + + expect(preview).not.toBeNull();if (!( + preview != null)) {throw new Error('Invariant violation: "preview != null"');} expect(preview.contents).toEqual( - dedent`def baz(test={ + (_dedent || _load_dedent()).default`def baz(test={ 'one': 'two' - }):`, - ); - }); + }):`); + + })); }); it("doesn't dedent beyond the current lines indentation level", () => { - waitsForPromise(async () => { - const preview = await getDefinitionPreview( - javascriptFixtureDefinitionWithPoint(new Point(36, 18)), - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const preview = yield (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)( + javascriptFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(36, 18))); - expect(preview).not.toBeNull(); - invariant(preview != null); + + expect(preview).not.toBeNull();if (!( + preview != null)) {throw new Error('Invariant violation: "preview != null"');} expect(preview.contents).toEqual( - dedent` + (_dedent || _load_dedent()).default` export function aPoorlyIndentedFunction( aReallyReallyLongArgumentNameThatWouldRequireThisToBreakAcrossMultipleLines: Something, ): number { - `, - ); - }); + `); + + })); }); it('reads until the indentation returns to initial and parens are balanced', () => { - waitsForPromise(async () => { - const preview = await getDefinitionPreview( - javascriptFixtureDefinitionWithPoint(new Point(30, 16)), - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const preview = yield (0, (_symbolDefinitionPreview || _load_symbolDefinitionPreview()).getDefinitionPreview)( + javascriptFixtureDefinitionWithPoint(new (_simpleTextBuffer || _load_simpleTextBuffer()).Point(30, 16))); - expect(preview).not.toBeNull(); - invariant(preview != null); + + expect(preview).not.toBeNull();if (!( + preview != null)) {throw new Error('Invariant violation: "preview != null"');} expect(preview.contents).toEqual( - dedent` + (_dedent || _load_dedent()).default` export function aMultiLineFunctionSignature( aReallyReallyLongArgumentNameThatWouldRequireThisToBreakAcrossMultipleLines: Something, ): number { - `, - ); - }); + `); + + })); }); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/spec/test-helpers-spec.js b/modules/nuclide-commons/spec/test-helpers-spec.js index 17071821..5f4d8462 100644 --- a/modules/nuclide-commons/spec/test-helpers-spec.js +++ b/modules/nuclide-commons/spec/test-helpers-spec.js @@ -1,65 +1,65 @@ -/** - * 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 - * @format - */ - -import typeof * as TestModuleType from './fixtures/toBeTested'; - -import fs from 'fs'; -import glob from 'glob'; -import nuclideUri from '../nuclideUri'; -import { - arePropertiesEqual, - clearRequireCache, - expectAsyncFailure, - generateFixture, - uncachedRequire, -} from '../test-helpers'; +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + + + + + + + + + + + + + +var _fs = _interopRequireDefault(require('fs'));var _glob; +function _load_glob() {return _glob = _interopRequireDefault(require('glob'));}var _nuclideUri; +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('../nuclideUri'));}var _testHelpers; +function _load_testHelpers() {return _testHelpers = require('../test-helpers');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + + + + + + describe('arePropertiesEqual', () => { it('correctly compares empty objects', () => { - expect(arePropertiesEqual({}, {})).toBe(true); + expect((0, (_testHelpers || _load_testHelpers()).arePropertiesEqual)({}, {})).toBe(true); }); it('correctly compares objects with the same properties', () => { - expect(arePropertiesEqual({foo: 5}, {foo: 5})).toBe(true); + expect((0, (_testHelpers || _load_testHelpers()).arePropertiesEqual)({ foo: 5 }, { foo: 5 })).toBe(true); }); it('allows one property to be undefined while another does not exist at all', () => { - expect(arePropertiesEqual({foo: undefined}, {})).toBe(true); + expect((0, (_testHelpers || _load_testHelpers()).arePropertiesEqual)({ foo: undefined }, {})).toBe(true); }); it('returns false when properties are not equal', () => { - expect(arePropertiesEqual({foo: 5}, {foo: 4})).toBe(false); + expect((0, (_testHelpers || _load_testHelpers()).arePropertiesEqual)({ foo: 5 }, { foo: 4 })).toBe(false); }); it('returns false when one property is undefined and another is defined', () => { - expect(arePropertiesEqual({foo: 5}, {foo: undefined})).toBe(false); - expect(arePropertiesEqual({foo: undefined}, {foo: 5})).toBe(false); + expect((0, (_testHelpers || _load_testHelpers()).arePropertiesEqual)({ foo: 5 }, { foo: undefined })).toBe(false); + expect((0, (_testHelpers || _load_testHelpers()).arePropertiesEqual)({ foo: undefined }, { foo: 5 })).toBe(false); }); it('returns false when one property exists but the other does not', () => { - expect(arePropertiesEqual({foo: 5}, {})).toBe(false); - expect(arePropertiesEqual({}, {foo: 5})).toBe(false); + expect((0, (_testHelpers || _load_testHelpers()).arePropertiesEqual)({ foo: 5 }, {})).toBe(false); + expect((0, (_testHelpers || _load_testHelpers()).arePropertiesEqual)({}, { foo: 5 })).toBe(false); }); -}); - -describe('expectAsyncFailure', () => { - it('fails when provided Promise succeeds', () => { - const verify: any = jasmine.createSpy(); - waitsForPromise({shouldReject: true}, () => { - return expectAsyncFailure( - Promise.resolve('resolved, not rejected!'), - verify, - ); - }); +}); /** + * 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. + * + * + * @format + */describe('expectAsyncFailure', () => {it('fails when provided Promise succeeds', () => {const verify = jasmine.createSpy();waitsForPromise({ shouldReject: true }, () => {return (0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)(Promise.resolve('resolved, not rejected!'), verify);}); runs(() => { expect(verify.callCount).toBe(0); }); @@ -75,8 +75,8 @@ describe('expectAsyncFailure', () => { } } - waitsForPromise({shouldReject: true}, () => { - return expectAsyncFailure(Promise.reject(Error('I failed.')), verify); + waitsForPromise({ shouldReject: true }, () => { + return (0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)(Promise.reject(Error('I failed.')), verify); }); runs(() => { expect(callCount).toBe(1); @@ -93,11 +93,11 @@ describe('expectAsyncFailure', () => { } } - waitsForPromise({shouldReject: false}, () => { - return expectAsyncFailure( - Promise.reject(Error('I failed badly.')), - verify, - ); + waitsForPromise({ shouldReject: false }, () => { + return (0, (_testHelpers || _load_testHelpers()).expectAsyncFailure)( + Promise.reject(Error('I failed badly.')), + verify); + }); runs(() => { expect(callCount).toBe(1); @@ -107,58 +107,58 @@ describe('expectAsyncFailure', () => { describe('generateFixture', () => { it('should create the directory hierarchy', () => { - waitsForPromise(async () => { - const fixturePath = await generateFixture( - 'fixture-to-generate', - new Map([['foo.js', undefined], ['bar/baz.txt', 'some text']]), - ); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const fixturePath = yield (0, (_testHelpers || _load_testHelpers()).generateFixture)( + 'fixture-to-generate', + new Map([['foo.js', undefined], ['bar/baz.txt', 'some text']])); - expect(nuclideUri.isAbsolute(fixturePath)).toBe(true); - expect(fs.statSync(fixturePath).isDirectory()).toBe(true); - const fooPath = nuclideUri.join(fixturePath, 'foo.js'); - const bazPath = nuclideUri.join(fixturePath, 'bar/baz.txt'); + expect((_nuclideUri || _load_nuclideUri()).default.isAbsolute(fixturePath)).toBe(true); + expect(_fs.default.statSync(fixturePath).isDirectory()).toBe(true); - expect(fs.statSync(fooPath).isFile()).toBe(true); - expect(fs.statSync(bazPath).isFile()).toBe(true); + const fooPath = (_nuclideUri || _load_nuclideUri()).default.join(fixturePath, 'foo.js'); + const bazPath = (_nuclideUri || _load_nuclideUri()).default.join(fixturePath, 'bar/baz.txt'); - expect(fs.readFileSync(fooPath, 'utf8')).toBe(''); - expect(fs.readFileSync(bazPath, 'utf8')).toBe('some text'); - }); + expect(_fs.default.statSync(fooPath).isFile()).toBe(true); + expect(_fs.default.statSync(bazPath).isFile()).toBe(true); + + expect(_fs.default.readFileSync(fooPath, 'utf8')).toBe(''); + expect(_fs.default.readFileSync(bazPath, 'utf8')).toBe('some text'); + })); }); it('should work with lots of files', () => { - waitsForPromise({timeout: 10000}, async () => { + waitsForPromise({ timeout: 10000 }, (0, _asyncToGenerator.default)(function* () { const files = new Map(); for (let i = 0; i < 10; i++) { for (let j = 0; j < 1000; j++) { files.set(`dir_${i}/file_${j}.txt`, `${i} + ${j} = ${i + j}`); } } - const fixturePath = await generateFixture('lots-of-files', files); - const fixtureFiles = glob.sync( - nuclideUri.join(fixturePath, 'dir_*/file_*.txt'), - ); + const fixturePath = yield (0, (_testHelpers || _load_testHelpers()).generateFixture)('lots-of-files', files); + const fixtureFiles = (_glob || _load_glob()).default.sync( + (_nuclideUri || _load_nuclideUri()).default.join(fixturePath, 'dir_*/file_*.txt')); + expect(fixtureFiles.length).toBe(10000); - }); + })); }); it('should work with no files', () => { - waitsForPromise(async () => { - const fixturePath = await generateFixture('fixture-empty', new Map()); - expect(nuclideUri.isAbsolute(fixturePath)).toBe(true); - expect(fs.statSync(fixturePath).isDirectory()).toBe(true); - expect(fs.readdirSync(fixturePath)).toEqual([]); - }); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const fixturePath = yield (0, (_testHelpers || _load_testHelpers()).generateFixture)('fixture-empty', new Map()); + expect((_nuclideUri || _load_nuclideUri()).default.isAbsolute(fixturePath)).toBe(true); + expect(_fs.default.statSync(fixturePath).isDirectory()).toBe(true); + expect(_fs.default.readdirSync(fixturePath)).toEqual([]); + })); }); it('works with no files arg', () => { - waitsForPromise(async () => { - const fixturePath = await generateFixture('fixture-empty'); - expect(nuclideUri.isAbsolute(fixturePath)).toBe(true); - expect(fs.statSync(fixturePath).isDirectory()).toBe(true); - expect(fs.readdirSync(fixturePath)).toEqual([]); - }); + waitsForPromise((0, _asyncToGenerator.default)(function* () { + const fixturePath = yield (0, (_testHelpers || _load_testHelpers()).generateFixture)('fixture-empty'); + expect((_nuclideUri || _load_nuclideUri()).default.isAbsolute(fixturePath)).toBe(true); + expect(_fs.default.statSync(fixturePath).isDirectory()).toBe(true); + expect(_fs.default.readdirSync(fixturePath)).toEqual([]); + })); }); }); @@ -167,18 +167,18 @@ describe('Mocking Imports test suite', () => { it('Mocking imported dependencies', () => { // 1 - First mock all functions imported by the module under test const mock = spyOn( - require('./fixtures/toBeMocked'), - 'importedFunction', - ).andReturn(45); + require('./fixtures/toBeMocked'), + 'importedFunction'). + andReturn(45); // 2 - Do an uncachedRequire of the module to test // Note the 'import typeof * as ... ' above to get type checking // for the functions to be tested. // You may want to put steps 1 & 2 in your beforeEach. - const moduleToTest: TestModuleType = (uncachedRequire( - require, - './fixtures/toBeTested', - ): any); + const moduleToTest = (0, (_testHelpers || _load_testHelpers()).uncachedRequire)( + require, + './fixtures/toBeTested'); + // 3 - Perform your test const result = moduleToTest.functionToTest(); @@ -187,6 +187,6 @@ describe('Mocking Imports test suite', () => { // 4 - Reset the require cache so your mocks don't get used for other tests. // You may want to put this in your afterEach. - clearRequireCache(require, './fixtures/toBeTested'); + (0, (_testHelpers || _load_testHelpers()).clearRequireCache)(require, './fixtures/toBeTested'); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/spec/which-spec.js b/modules/nuclide-commons/spec/which-spec.js index 230ee102..01fc6ba7 100644 --- a/modules/nuclide-commons/spec/which-spec.js +++ b/modules/nuclide-commons/spec/which-spec.js @@ -1,27 +1,27 @@ -/** - * 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 - * @format - */ - -import which from '../which'; -import {Observable} from 'rxjs'; - -describe('which', () => { - let runCommand: JasmineSpy; - let runCommandReturn = ''; - - beforeEach(() => { - runCommandReturn = ''; - runCommand = spyOn(require('../process'), 'runCommand').andCallFake(() => - Observable.of(runCommandReturn), - ); +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _which; + + + + + + + + + + + +function _load_which() {return _which = _interopRequireDefault(require('../which'));} +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */describe('which', () => {let runCommand;let runCommandReturn = '';beforeEach(() => {runCommandReturn = '';runCommand = spyOn(require('../process'), 'runCommand').andCallFake(() => _rxjsBundlesRxMinJs.Observable.of(runCommandReturn)); }); afterEach(() => { @@ -29,60 +29,60 @@ describe('which', () => { }); describe('on windows', () => { - const real_platform: string = process.platform; + const real_platform = process.platform; const eol = '\r\n'; const os = require('os'); const real_eol = os.EOL; beforeEach(() => { - Object.defineProperty(process, 'platform', {value: 'win32'}); + Object.defineProperty(process, 'platform', { value: 'win32' }); os.EOL = eol; }); afterEach(() => { - Object.defineProperty(process, 'platform', {value: real_platform}); + Object.defineProperty(process, 'platform', { value: real_platform }); os.EOL = real_eol; }); it('calls where on Windows', () => { - const param: string = ''; - which(param); + const param = ''; + (0, (_which || _load_which()).default)(param); expect(runCommand).toHaveBeenCalledWith('where', ['']); }); it('returns the first match', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { runCommandReturn = 'hello' + os.EOL + 'hello.exe' + os.EOL; - const ret = await which('bla'); + const ret = yield (0, (_which || _load_which()).default)('bla'); expect(ret).toEqual('hello'); - }); + })); }); }); describe('on linux', () => { - const real_platform: string = process.platform; + const real_platform = process.platform; const eol = '\n'; const os = require('os'); const real_eol = os.EOL; beforeEach(() => { - Object.defineProperty(process, 'platform', {value: 'linux'}); + Object.defineProperty(process, 'platform', { value: 'linux' }); os.EOL = eol; }); afterEach(() => { - Object.defineProperty(process, 'platform', {value: real_platform}); + Object.defineProperty(process, 'platform', { value: real_platform }); os.EOL = real_eol; }); it('calls which', () => { - const param: string = ''; - which(param); + const param = ''; + (0, (_which || _load_which()).default)(param); expect(runCommand).toHaveBeenCalledWith('which', [param]); }); it('returns the first match', () => { - waitsForPromise(async () => { + waitsForPromise((0, _asyncToGenerator.default)(function* () { runCommandReturn = 'hello' + os.EOL + '/bin/hello' + os.EOL; - const ret = await which('bla'); + const ret = yield (0, (_which || _load_which()).default)('bla'); expect(ret).toEqual('hello'); - }); + })); }); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-commons/stream.js b/modules/nuclide-commons/stream.js index 936d0f1d..92f3bc05 100644 --- a/modules/nuclide-commons/stream.js +++ b/modules/nuclide-commons/stream.js @@ -1,74 +1,74 @@ -/** - * 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 - * @format - */ - -import Stream from 'stream'; -import {Observable} from 'rxjs'; - -import UniversalDisposable from './UniversalDisposable'; -import {attachEvent} from './event'; - -/** - * Observe a stream like stdout or stderr. - */ -export function observeStream(stream: stream$Readable): Observable { - return observeRawStream(stream).map(data => data.toString()); -} - -export function observeRawStream(stream: stream$Readable): Observable { - const error = Observable.fromEvent(stream, 'error').flatMap(Observable.throw); - return Observable.fromEvent(stream, 'data') - .merge(error) - .takeUntil(Observable.fromEvent(stream, 'end')); -} - -/** - * Write an observed readable stream into a writable stream. Effectively a pipe() for observables. - * Returns an observable accumulating the number of bytes processed. - */ -export function writeToStream( - source: Observable, - destStream: stream$Writable, -): Observable { - return Observable.create(observer => { - let byteCount = 0; - - const byteCounterStream = new Stream.Transform({ - transform(chunk, encoding, cb) { - byteCount += chunk.byteLength; - observer.next(byteCount); - cb(null, chunk); - }, - }); - - byteCounterStream.pipe(destStream); - - return new UniversalDisposable( - attachEvent(destStream, 'error', err => { - observer.error(err); - }), - attachEvent(destStream, 'close', () => { - observer.complete(); - }), - source.subscribe( - buffer => { - byteCounterStream.write(buffer); - }, - err => { - observer.error(err); - }, - () => { - byteCounterStream.end(); - }, - ), - ); +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + + + + + + + + +observeStream = observeStream;exports. + + + +observeRawStream = observeRawStream;exports. + + + + + + + + + + +writeToStream = writeToStream;var _stream = _interopRequireDefault(require('stream'));var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _UniversalDisposable;function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('./UniversalDisposable'));}var _event;function _load_event() {return _event = require('./event');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * Observe a stream like stdout or stderr. + */ /** + * 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. + * + * + * @format + */function observeStream(stream) {return observeRawStream(stream).map(data => data.toString());}function observeRawStream(stream) {const error = _rxjsBundlesRxMinJs.Observable.fromEvent(stream, 'error').flatMap(_rxjsBundlesRxMinJs.Observable.throw);return _rxjsBundlesRxMinJs.Observable.fromEvent(stream, 'data').merge(error).takeUntil(_rxjsBundlesRxMinJs.Observable.fromEvent(stream, 'end'));} /** + * Write an observed readable stream into a writable stream. Effectively a pipe() for observables. + * Returns an observable accumulating the number of bytes processed. + */function writeToStream(source, destStream) {return _rxjsBundlesRxMinJs.Observable.create(observer => {let byteCount = 0;const byteCounterStream = new _stream.default.Transform({ transform(chunk, encoding, cb) {byteCount += chunk.byteLength;observer.next(byteCount);cb(null, chunk);} });byteCounterStream.pipe(destStream); + + return new (_UniversalDisposable || _load_UniversalDisposable()).default( + (0, (_event || _load_event()).attachEvent)(destStream, 'error', err => { + observer.error(err); + }), + (0, (_event || _load_event()).attachEvent)(destStream, 'close', () => { + observer.complete(); + }), + source.subscribe( + buffer => { + byteCounterStream.write(buffer); + }, + err => { + observer.error(err); + }, + () => { + byteCounterStream.end(); + })); + + }).share(); -} +} \ No newline at end of file diff --git a/modules/nuclide-commons/string.js b/modules/nuclide-commons/string.js index c6c09a93..94c360b1 100644 --- a/modules/nuclide-commons/string.js +++ b/modules/nuclide-commons/string.js @@ -1,269 +1,299 @@ -/** - * 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 - * @format - */ - -import invariant from 'assert'; -import {parse, quote} from './_shell-quote'; - -export function stringifyError(error: Error): string { - return `name: ${error.name}, message: ${error.message}, stack: ${ - error.stack - }.`; -} - -// As of Flow v0.28, Flow does not alllow implicit string coercion of null or undefined. Use this to +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.ELLIPSIS_CHAR = exports.URL_REGEX = undefined;exports. + + + + + + + + + + + + + + +stringifyError = stringifyError;exports. + + + + + + + +maybeToString = maybeToString;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +relativeDate = relativeDate;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +countOccurrences = countOccurrences;exports. + + + + + + + + + + + + + + + + +shellParse = shellParse;exports. + + + + + + + + + + + + + + + + + + + + + +shellQuote = shellQuote;exports. + + + +removeCommonPrefix = removeCommonPrefix;exports. + + + + + + + +removeCommonSuffix = removeCommonSuffix;exports. + + + + + + + + + + + +shorten = shorten;exports. + + + + + + + + + + + + +splitOnce = splitOnce;exports. + + + + + + + + + +indent = indent;exports. + + + + + + + +pluralize = pluralize;exports. + + + +capitalize = capitalize;exports. + + + + + + + + + + + + + + + +getMatchRanges = getMatchRanges;exports. + + + + + + + + + + + + + + + + + + + + + + +escapeMarkdown = escapeMarkdown;var _shellQuote;function _load_shellQuote() {return _shellQuote = require('./_shell-quote');} /** + * 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. + * + * + * @format + */function stringifyError(error) {return `name: ${error.name}, message: ${error.message}, stack: ${error.stack}.`;} // As of Flow v0.28, Flow does not alllow implicit string coercion of null or undefined. Use this to // make it explicit. -export function maybeToString(str: ?string): string { - // We don't want to encourage the use of this function directly because it coerces anything to a +function maybeToString(str) {// We don't want to encourage the use of this function directly because it coerces anything to a // string. We get stricter typechecking by using maybeToString, so it should generally be // preferred. - return String(str); -} - -/** - * Originally adapted from https://github.com/azer/relative-date. - * We're including it because of https://github.com/npm/npm/issues/12012 - */ -const SECOND = 1000; -const MINUTE = 60 * SECOND; -const HOUR = 60 * MINUTE; -const DAY = 24 * HOUR; -const WEEK = 7 * DAY; -const YEAR = DAY * 365; -const MONTH = YEAR / 12; - -const shortFormats = [ - [0.7 * MINUTE, 'now'], - [1.5 * MINUTE, '1m'], - [60 * MINUTE, 'm', MINUTE], - [1.5 * HOUR, '1h'], - [DAY, 'h', HOUR], - [2 * DAY, '1d'], - [7 * DAY, 'd', DAY], - [1.5 * WEEK, '1w'], - [MONTH, 'w', WEEK], - [1.5 * MONTH, '1mo'], - [YEAR, 'mo', MONTH], - [1.5 * YEAR, '1y'], - [Number.MAX_VALUE, 'y', YEAR], -]; - -const longFormats = [ - [0.7 * MINUTE, 'just now'], - [1.5 * MINUTE, 'a minute ago'], - [60 * MINUTE, 'minutes ago', MINUTE], - [1.5 * HOUR, 'an hour ago'], - [DAY, 'hours ago', HOUR], - [2 * DAY, 'yesterday'], - [7 * DAY, 'days ago', DAY], - [1.5 * WEEK, 'a week ago'], - [MONTH, 'weeks ago', WEEK], - [1.5 * MONTH, 'a month ago'], - [YEAR, 'months ago', MONTH], - [1.5 * YEAR, 'a year ago'], - [Number.MAX_VALUE, 'years ago', YEAR], -]; - -export function relativeDate( - input_: number | Date, - reference_?: number | Date, - useShortVariant?: boolean = false, -): string { - let input = input_; - let reference = reference_; - if (input instanceof Date) { - input = input.getTime(); - } - // flowlint-next-line sketchy-null-number:off - if (!reference) { - reference = new Date().getTime(); - } - if (reference instanceof Date) { - reference = reference.getTime(); - } - - const delta = reference - input; - const formats = useShortVariant ? shortFormats : longFormats; - for (const [limit, relativeFormat, remainder] of formats) { - if (delta < limit) { - if (typeof remainder === 'number') { - return ( - Math.round(delta / remainder) + - (useShortVariant ? '' : ' ') + - relativeFormat - ); - } else { - return relativeFormat; - } - } - } - - throw new Error('This should never be reached.'); -} - -/** - * Count the number of occurrences of `char` in `str`. - * `char` must be a string of length 1. - */ -export function countOccurrences(haystack: string, char: string) { - invariant(char.length === 1, 'char must be a string of length 1'); - - let count = 0; - const code = char.charCodeAt(0); - for (let i = 0; i < haystack.length; i++) { - if (haystack.charCodeAt(i) === code) { - count++; - } - } - return count; -} - -/** - * shell-quote's parse allows pipe operators and comments. - * Generally users don't care about this, so throw if we encounter any operators. - */ -export function shellParse(str: string, env?: Object): Array { - const result = parse(str, env); - for (let i = 0; i < result.length; i++) { - if (typeof result[i] !== 'string') { - if (result[i].op != null) { - throw new Error( - `Unexpected operator "${result[i].op}" provided to shellParse`, - ); - } else { - throw new Error( - `Unexpected comment "${result[i].comment}" provided to shellParse`, - ); - } - } - } - return result; -} - -/** - * Technically you can pass in { operator: string } here, - * but we don't use that in most APIs. - */ -export function shellQuote(args: Array): string { - return quote(args); -} - -export function removeCommonPrefix(a: string, b: string): [string, string] { - let i = 0; - while (a[i] === b[i] && i < a.length && i < b.length) { - i++; - } - return [a.substring(i), b.substring(i)]; -} - -export function removeCommonSuffix(a: string, b: string): [string, string] { - let i = 0; - while ( - a[a.length - 1 - i] === b[b.length - 1 - i] && - i < a.length && - i < b.length - ) { - i++; - } - return [a.substring(0, a.length - i), b.substring(0, b.length - i)]; -} - -export function shorten( - str: string, - maxLength: number, - suffix?: string, -): string { - return str.length < maxLength - ? str - : str.slice(0, maxLength) + (suffix || ''); -} - -/** - * Like String.split, but only splits once. - */ -export function splitOnce(str: string, separator: string): [string, ?string] { - const index = str.indexOf(separator); - return index === -1 - ? [str, null] - : [str.slice(0, index), str.slice(index + separator.length)]; -} - -/** - * Indents each line by the specified number of characters. - */ -export function indent( - str: string, - level: number = 2, - char: string = ' ', -): string { - return str.replace(/^([^\n])/gm, char.repeat(level) + '$1'); -} - -export function pluralize(noun: string, count: number) { - return count === 1 ? noun : noun + 's'; -} - -export function capitalize(str: string): string { - return str.length === 0 - ? str - : str - .charAt(0) - .toUpperCase() - .concat(str.slice(1)); -} - -type MatchRange = [/* start */ number, /* end */ number]; - -/** - * Returns a list of ranges where needle occurs in haystack. - * This will *not* return overlapping matches; i.e. the returned list will be disjoint. - * This makes it easier to use for e.g. highlighting matches in a UI. - */ -export function getMatchRanges( - haystack: string, - needle: string, -): Array { - if (needle === '') { - // Not really a valid use. - return []; - } - - const ranges = []; - let matchIndex = 0; - while ((matchIndex = haystack.indexOf(needle, matchIndex)) !== -1) { - const prevRange = ranges[ranges.length - 1]; - if (prevRange != null && prevRange[1] === matchIndex) { - prevRange[1] += needle.length; - } else { - ranges.push([matchIndex, matchIndex + needle.length]); - } - matchIndex += needle.length; - } - return ranges; -} - -export function escapeMarkdown(markdown: string): string { - // _ * # () [] need to be slash escaped. - const slashEscaped = markdown.replace(/[_*#/()[\]]/g, '\\$&'); - // And HTML tags need to be < > escaped. - return slashEscaped.replace(//g, '>'); -} - -// Originally copied from: + return String(str);} /** + * Originally adapted from https://github.com/azer/relative-date. + * We're including it because of https://github.com/npm/npm/issues/12012 + */const SECOND = 1000;const MINUTE = 60 * SECOND;const HOUR = 60 * MINUTE;const DAY = 24 * HOUR;const WEEK = 7 * DAY;const YEAR = DAY * 365;const MONTH = YEAR / 12;const shortFormats = [[0.7 * MINUTE, 'now'], [1.5 * MINUTE, '1m'], [60 * MINUTE, 'm', MINUTE], [1.5 * HOUR, '1h'], [DAY, 'h', HOUR], [2 * DAY, '1d'], [7 * DAY, 'd', DAY], [1.5 * WEEK, '1w'], [MONTH, 'w', WEEK], [1.5 * MONTH, '1mo'], [YEAR, 'mo', MONTH], [1.5 * YEAR, '1y'], [Number.MAX_VALUE, 'y', YEAR]];const longFormats = [[0.7 * MINUTE, 'just now'], [1.5 * MINUTE, 'a minute ago'], [60 * MINUTE, 'minutes ago', MINUTE], [1.5 * HOUR, 'an hour ago'], [DAY, 'hours ago', HOUR], [2 * DAY, 'yesterday'], [7 * DAY, 'days ago', DAY], [1.5 * WEEK, 'a week ago'], [MONTH, 'weeks ago', WEEK], [1.5 * MONTH, 'a month ago'], [YEAR, 'months ago', MONTH], [1.5 * YEAR, 'a year ago'], [Number.MAX_VALUE, 'years ago', YEAR]];function relativeDate(input_, reference_, useShortVariant = false) {let input = input_;let reference = reference_;if (input instanceof Date) {input = input.getTime();} // flowlint-next-line sketchy-null-number:off + if (!reference) {reference = new Date().getTime();}if (reference instanceof Date) {reference = reference.getTime();}const delta = reference - input;const formats = useShortVariant ? shortFormats : longFormats;for (const [limit, relativeFormat, remainder] of formats) {if (delta < limit) {if (typeof remainder === 'number') {return Math.round(delta / remainder) + (useShortVariant ? '' : ' ') + relativeFormat;} else {return relativeFormat;}}}throw new Error('This should never be reached.');} /** + * Count the number of occurrences of `char` in `str`. + * `char` must be a string of length 1. + */function countOccurrences(haystack, char) {if (!(char.length === 1)) {throw new Error('char must be a string of length 1');}let count = 0;const code = char.charCodeAt(0);for (let i = 0; i < haystack.length; i++) {if (haystack.charCodeAt(i) === code) {count++;}}return count;} /** + * shell-quote's parse allows pipe operators and comments. + * Generally users don't care about this, so throw if we encounter any operators. + */function shellParse(str, env) {const result = (0, (_shellQuote || _load_shellQuote()).parse)(str, env);for (let i = 0; i < result.length; i++) {if (typeof result[i] !== 'string') {if (result[i].op != null) {throw new Error(`Unexpected operator "${result[i].op}" provided to shellParse`);} else {throw new Error(`Unexpected comment "${result[i].comment}" provided to shellParse`);}}}return result;} /** + * Technically you can pass in { operator: string } here, + * but we don't use that in most APIs. + */function shellQuote(args) {return (0, (_shellQuote || _load_shellQuote()).quote)(args);}function removeCommonPrefix(a, b) {let i = 0;while (a[i] === b[i] && i < a.length && i < b.length) {i++;}return [a.substring(i), b.substring(i)];}function removeCommonSuffix(a, b) {let i = 0;while (a[a.length - 1 - i] === b[b.length - 1 - i] && i < a.length && i < b.length) {i++;}return [a.substring(0, a.length - i), b.substring(0, b.length - i)];}function shorten(str, maxLength, suffix) {return str.length < maxLength ? str : str.slice(0, maxLength) + (suffix || '');} /** + * Like String.split, but only splits once. + */function splitOnce(str, separator) {const index = str.indexOf(separator);return index === -1 ? [str, null] : [str.slice(0, index), str.slice(index + separator.length)];} /** + * Indents each line by the specified number of characters. + */function indent(str, level = 2, char = ' ') {return str.replace(/^([^\n])/gm, char.repeat(level) + '$1');}function pluralize(noun, count) {return count === 1 ? noun : noun + 's';}function capitalize(str) {return str.length === 0 ? str : str.charAt(0).toUpperCase().concat(str.slice(1));} /** + * Returns a list of ranges where needle occurs in haystack. + * This will *not* return overlapping matches; i.e. the returned list will be disjoint. + * This makes it easier to use for e.g. highlighting matches in a UI. + */function getMatchRanges(haystack, needle) {if (needle === '') {// Not really a valid use. + return [];}const ranges = [];let matchIndex = 0;while ((matchIndex = haystack.indexOf(needle, matchIndex)) !== -1) {const prevRange = ranges[ranges.length - 1];if (prevRange != null && prevRange[1] === matchIndex) {prevRange[1] += needle.length;} else {ranges.push([matchIndex, matchIndex + needle.length]);}matchIndex += needle.length;}return ranges;}function escapeMarkdown(markdown) {// _ * # () [] need to be slash escaped. + const slashEscaped = markdown.replace(/[_*#/()[\]]/g, '\\$&'); // And HTML tags need to be < > escaped. + return slashEscaped.replace(//g, '>');} // Originally copied from: // http://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url // But adopted to match `www.` urls as well as `https?` urls // and `!` as acceptable url piece. // Then optimized with https://www.npmjs.com/package/regexp-tree. // Added a single matching group for use with String.split. // eslint-disable-next-line max-len -export const URL_REGEX = /(https?:\/\/(?:www\.)?[-\w@:%.+~#=]{2,256}\.[a-z]{2,6}\b[-\w@:%+.~#?&/=!]*|www\.[-\w@:%.+~#=]{2,256}\.[a-z]{2,6}\b[-\w@:%+.~#?&/=!]*)/; - -export const ELLIPSIS_CHAR = '\u2026'; +const URL_REGEX = exports.URL_REGEX = /(https?:\/\/(?:www\.)?[-\w@:%.+~#=]{2,256}\.[a-z]{2,6}\b[-\w@:%+.~#?&/=!]*|www\.[-\w@:%.+~#=]{2,256}\.[a-z]{2,6}\b[-\w@:%+.~#?&/=!]*)/;const ELLIPSIS_CHAR = exports.ELLIPSIS_CHAR = '\u2026'; \ No newline at end of file diff --git a/modules/nuclide-commons/symbol-definition-preview.js b/modules/nuclide-commons/symbol-definition-preview.js index 9371c3cf..78639d69 100644 --- a/modules/nuclide-commons/symbol-definition-preview.js +++ b/modules/nuclide-commons/symbol-definition-preview.js @@ -1,101 +1,111 @@ -/** - * 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 - * @format - */ - -import type {NuclideUri} from './nuclideUri'; -import mimeTypes from 'mime-types'; -import fsPromise from './fsPromise'; -import {countOccurrences} from './string'; -import nuclideUri from './nuclideUri'; - -type Definition = { - path: NuclideUri, - position: atom$Point, -}; - -const MAX_PREVIEW_LINES = 10; -const MAX_FILESIZE = 100000; -const WHITESPACE_REGEX = /^\s*/; -function getIndentLevel(line: string) { - return WHITESPACE_REGEX.exec(line)[0].length; -} - -export async function getDefinitionPreview( - definition: Definition, -): Promise { - // ensure filesize not too big before reading in whole file - const stats = await fsPromise.stat(definition.path); - if (stats.size > MAX_FILESIZE) { - return null; - } - - // if file is image, return base-64 encoded contents - const fileBuffer = await fsPromise.readFile(definition.path); - - const mime = - mimeTypes.contentType(nuclideUri.extname(definition.path)) || 'text/plain'; - if (mime.startsWith('image/')) { - return {mime, contents: fileBuffer.toString('base64'), encoding: 'base64'}; - } - - const contents = fileBuffer.toString('utf8'); - const lines = contents.split('\n'); - - const start = definition.position.row; - const initialIndentLevel = getIndentLevel(lines[start]); - - const buffer = []; - for ( +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.getDefinitionPreview = undefined;var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));let getDefinitionPreview = exports.getDefinitionPreview = (() => {var _ref = (0, _asyncToGenerator.default)( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + function* ( + definition) + + + + + { + // ensure filesize not too big before reading in whole file + const stats = yield (_fsPromise || _load_fsPromise()).default.stat(definition.path); + if (stats.size > MAX_FILESIZE) { + return null; + } + + // if file is image, return base-64 encoded contents + const fileBuffer = yield (_fsPromise || _load_fsPromise()).default.readFile(definition.path); + + const mime = + (_mimeTypes || _load_mimeTypes()).default.contentType((_nuclideUri || _load_nuclideUri()).default.extname(definition.path)) || 'text/plain'; + if (mime.startsWith('image/')) { + return { mime, contents: fileBuffer.toString('base64'), encoding: 'base64' }; + } + + const contents = fileBuffer.toString('utf8'); + const lines = contents.split('\n'); + + const start = definition.position.row; + const initialIndentLevel = getIndentLevel(lines[start]); + + const buffer = []; + for ( let i = start, - openParenCount = 0, - closedParenCount = 0, - openCurlyCount = 0, - closedCurlyCount = 0; + openParenCount = 0, + closedParenCount = 0, + openCurlyCount = 0, + closedCurlyCount = 0; i < start + MAX_PREVIEW_LINES && i < lines.length; - i++ - ) { - const line = lines[i]; - const indentLevel = getIndentLevel(line); - openParenCount += countOccurrences(line, '('); - closedParenCount += countOccurrences(line, ')'); - openCurlyCount += countOccurrences(line, '{'); - closedCurlyCount += countOccurrences(line, '}'); - - buffer.push(line.substr(Math.min(indentLevel, initialIndentLevel))); // dedent - - // heuristic for the end of a function signature: - if (indentLevel <= initialIndentLevel) { - // we've returned back to the original indentation level - if (openParenCount > 0 && openParenCount === closedParenCount) { - // if we're in a fn definition, make sure we have balanced pairs of parens - break; - } else if (line.trim().endsWith(';')) { - // c-style statement ending - break; - } else if ( + i++) + { + const line = lines[i]; + const indentLevel = getIndentLevel(line); + openParenCount += (0, (_string || _load_string()).countOccurrences)(line, '('); + closedParenCount += (0, (_string || _load_string()).countOccurrences)(line, ')'); + openCurlyCount += (0, (_string || _load_string()).countOccurrences)(line, '{'); + closedCurlyCount += (0, (_string || _load_string()).countOccurrences)(line, '}'); + + buffer.push(line.substr(Math.min(indentLevel, initialIndentLevel))); // dedent + + // heuristic for the end of a function signature: + if (indentLevel <= initialIndentLevel) { + // we've returned back to the original indentation level + if (openParenCount > 0 && openParenCount === closedParenCount) { + // if we're in a fn definition, make sure we have balanced pairs of parens + break; + } else if (line.trim().endsWith(';')) { + // c-style statement ending + break; + } else if ( // end of a property definition line.trim().endsWith(',') && // including complex types as values openCurlyCount === closedCurlyCount && // but still not before function signatures are closed - openParenCount === closedParenCount - ) { - break; + openParenCount === closedParenCount) + { + break; + } } } - } - return {mime, contents: buffer.join('\n'), encoding: 'utf8'}; -} + return { mime, contents: buffer.join('\n'), encoding: 'utf8' }; + });return function getDefinitionPreview(_x) {return _ref.apply(this, arguments);};})();var _mimeTypes;function _load_mimeTypes() {return _mimeTypes = _interopRequireDefault(require('mime-types'));}var _fsPromise;function _load_fsPromise() {return _fsPromise = _interopRequireDefault(require('./fsPromise'));}var _string;function _load_string() {return _string = require('./string');}var _nuclideUri;function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('./nuclideUri'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}const MAX_PREVIEW_LINES = 10; /** + * 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. + * + * + * @format + */const MAX_FILESIZE = 100000;const WHITESPACE_REGEX = /^\s*/;function getIndentLevel(line) {return WHITESPACE_REGEX.exec(line)[0].length;} \ No newline at end of file diff --git a/modules/nuclide-commons/test-helpers.js b/modules/nuclide-commons/test-helpers.js index 6136555d..fb2599a0 100644 --- a/modules/nuclide-commons/test-helpers.js +++ b/modules/nuclide-commons/test-helpers.js @@ -1,183 +1,183 @@ -/** - * 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 - * @format - */ - -import type {Observable} from 'rxjs'; - -import invariant from 'assert'; -import fs from 'fs'; -import temp from 'temp'; -import uuid from 'uuid'; -import fsPromise from './fsPromise'; -import nuclideUri from './nuclideUri'; -import {asyncLimit} from './promise'; - -invariant( - (typeof atom !== 'undefined' && atom.inSpecMode()) || - process.env.NODE_ENV === 'test', - 'Test helpers should only be used in spec mode', -); +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.generateFixture = exports.expectObservableToStartWith = exports.expectAsyncFailure = undefined;var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + + + + + + + + + + + + + + + + + + + + + + + -/** - * Verifies that a Promise fails with an Error with specific expectations. When - * running a test where a Promise is expected to fail, it is important to verify - * that it failed in the expected way to avoid false positives in test results. - * - * This function should be used with `await` inside `waitsForPromise()`. - * - * @param promise will be awaited. It is expected to reject. If it does not - * reject, then this function will return a rejected Promise. - * @param verify should confirm expectations about the Error produced by the - * rejection of `promise`. If these expectations are not met, then - * `verify()` must throw an exception. - */ -export async function expectAsyncFailure( - promise: Promise, - verify: (error: Error) => void, -): Promise { - try { - await promise; - return Promise.reject( - new Error('Promise should have failed, but did not.'), - ); - } catch (e) { - verify(e); - } -} -/** - * This is useful for mocking a module that the module under test requires. - * After setting up the mocks, you must invalidate the require cache and then - * re-require the module under test so that it picks up the mocked - * dependencies. - * - * The require parameter is needed because require is bound differently in each - * file, and we need to execute this in the caller's context. - */ -export function clearRequireCache(require: Object, module: string): void { - delete require.cache[require.resolve(module)]; -} - -export function uncachedRequire(require: Object, module: string): mixed { - clearRequireCache(require, module); - // $FlowIgnore - return require(module); -} -/** - * Jasmine has trouble spying on properties supplied by getters, so to make it - * work we have to get the value, delete the getter, and set the value as a - * property. - * - * This makes two assumptions: - * - The getter is idempotent (otherwise, callers in other tests might be - * surprised when the value here is returned) - * - The getter returns a function (otherwise, it doesn't make sense to spy on - * it) - */ -export function spyOnGetterValue(object: Object, f: string): JasmineSpy { - const value = object[f]; - delete object[f]; - object[f] = value; - return spyOn(object, f); -} /** - * Checks if the two objects have equal properties. This considers a property - * set to undefined to be equivalent to a property that was not set at all. - */ -export function arePropertiesEqual(obj1: Object, obj2: Object): boolean { - const allProps = new Set(); - function addAllProps(obj) { - for (const prop of Object.keys(obj)) { - allProps.add(prop); + * Verifies that a Promise fails with an Error with specific expectations. When + * running a test where a Promise is expected to fail, it is important to verify + * that it failed in the expected way to avoid false positives in test results. + * + * This function should be used with `await` inside `waitsForPromise()`. + * + * @param promise will be awaited. It is expected to reject. If it does not + * reject, then this function will return a rejected Promise. + * @param verify should confirm expectations about the Error produced by the + * rejection of `promise`. If these expectations are not met, then + * `verify()` must throw an exception. + */let expectAsyncFailure = exports.expectAsyncFailure = (() => {var _ref = (0, _asyncToGenerator.default)( + function* ( + promise, + verify) + { + try { + yield promise; + return Promise.reject( + new Error('Promise should have failed, but did not.')); + + } catch (e) { + verify(e); } - } - [obj1, obj2].forEach(addAllProps); - for (const prop of allProps) { - if (obj1[prop] !== obj2[prop]) { - return false; - } - } - return true; -} + });return function expectAsyncFailure(_x, _x2) {return _ref.apply(this, arguments);};})(); + +/** + * This is useful for mocking a module that the module under test requires. + * After setting up the mocks, you must invalidate the require cache and then + * re-require the module under test so that it picks up the mocked + * dependencies. + * + * The require parameter is needed because require is bound differently in each + * file, and we need to execute this in the caller's context. + */ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /** - * Warning: Callsites *must* await the resulting promise, or test failures may go unreported or - * misattributed. - */ -export async function expectObservableToStartWith( - source: Observable, - expected: Array, -): Promise { - const actual: Array = await source - .take(expected.length) - .toArray() - .toPromise(); - expect(actual).toEqual(expected); -} + * Warning: Callsites *must* await the resulting promise, or test failures may go unreported or + * misattributed. + */let expectObservableToStartWith = exports.expectObservableToStartWith = (() => {var _ref2 = (0, _asyncToGenerator.default)( + function* ( + source, + expected) + { + const actual = yield source. + take(expected.length). + toArray(). + toPromise(); + expect(actual).toEqual(expected); + });return function expectObservableToStartWith(_x3, _x4) {return _ref2.apply(this, arguments);};})(); /** - * Takes of Map of file/file-content pairs, and creates a temp dir that matches - * the file structure of the Map. Example: - * - * generateFixture('myfixture', new Map([ - * ['foo.js'], - * ['bar/baz.txt', 'some text'], - * ])); - * - * Creates: - * - * /tmp/myfixture_1/foo.js (empty file) - * /tmp/myfixture_1/bar/baz.txt (with 'some text') - */ -export async function generateFixture( - fixtureName: string, - files: ?Map, -): Promise { - temp.track(); - - const MAX_CONCURRENT_FILE_OPS = 100; - const tempDir = await fsPromise.tempdir(fixtureName); - - if (files == null) { - return tempDir; - } + * Takes of Map of file/file-content pairs, and creates a temp dir that matches + * the file structure of the Map. Example: + * + * generateFixture('myfixture', new Map([ + * ['foo.js'], + * ['bar/baz.txt', 'some text'], + * ])); + * + * Creates: + * + * /tmp/myfixture_1/foo.js (empty file) + * /tmp/myfixture_1/bar/baz.txt (with 'some text') + */let generateFixture = exports.generateFixture = (() => {var _ref3 = (0, _asyncToGenerator.default)( + function* ( + fixtureName, + files) + { + (_temp || _load_temp()).default.track(); + + const MAX_CONCURRENT_FILE_OPS = 100; + const tempDir = yield (_fsPromise || _load_fsPromise()).default.tempdir(fixtureName); + + if (files == null) { + return tempDir; + } - // Map -> Array with full paths - const fileTuples = Array.from(files, tuple => { - // It's our own array - it's ok to mutate it - tuple[0] = nuclideUri.join(tempDir, tuple[0]); - return tuple; - }); + // Map -> Array with full paths + const fileTuples = Array.from(files, function (tuple) { + // It's our own array - it's ok to mutate it + tuple[0] = (_nuclideUri || _load_nuclideUri()).default.join(tempDir, tuple[0]); + return tuple; + }); - // Dedupe the dirs that we have to make. - const dirsToMake = fileTuples - .map(([filename]) => nuclideUri.dirname(filename)) - .filter((dirname, i, arr) => arr.indexOf(dirname) === i); + // Dedupe the dirs that we have to make. + const dirsToMake = fileTuples. + map(function ([filename]) {return (_nuclideUri || _load_nuclideUri()).default.dirname(filename);}). + filter(function (dirname, i, arr) {return arr.indexOf(dirname) === i;}); - await asyncLimit(dirsToMake, MAX_CONCURRENT_FILE_OPS, dirname => - fsPromise.mkdirp(dirname), - ); + yield (0, (_promise || _load_promise()).asyncLimit)(dirsToMake, MAX_CONCURRENT_FILE_OPS, function (dirname) {return ( + (_fsPromise || _load_fsPromise()).default.mkdirp(dirname));}); - await asyncLimit( + + yield (0, (_promise || _load_promise()).asyncLimit)( fileTuples, MAX_CONCURRENT_FILE_OPS, - ([filename, contents]) => { + function ([filename, contents]) { // We can't use fsPromise/fs-plus because it does too much extra work. // They call `mkdirp` before `writeFile`. We know that the target dir // exists, so we can optimize by going straight to `fs`. When you're // making 10k files, this adds ~500ms. - return new Promise((resolve, reject) => { - fs.writeFile(filename, contents || '', err => { + return new Promise(function (resolve, reject) { + _fs.default.writeFile(filename, contents || '', function (err) { if (err) { reject(err); } else { @@ -185,21 +185,34 @@ export async function generateFixture( } }); }); - }, - ); - - return tempDir; -} - -export function writeCoverage(): void { - const {COVERAGE_DIR} = process.env; - if (COVERAGE_DIR != null) { - const coverage = global.__coverage__; - if (coverage != null) { - fs.writeFileSync( - nuclideUri.join(COVERAGE_DIR, uuid.v4() + '.json'), - JSON.stringify(coverage), - ); - } - } -} + }); + + + return tempDir; + });return function generateFixture(_x5, _x6) {return _ref3.apply(this, arguments);};})();exports.clearRequireCache = clearRequireCache;exports.uncachedRequire = uncachedRequire;exports.spyOnGetterValue = spyOnGetterValue;exports.arePropertiesEqual = arePropertiesEqual;exports. + +writeCoverage = writeCoverage;var _fs = _interopRequireDefault(require('fs'));var _temp;function _load_temp() {return _temp = _interopRequireDefault(require('temp'));}var _uuid;function _load_uuid() {return _uuid = _interopRequireDefault(require('uuid'));}var _fsPromise;function _load_fsPromise() {return _fsPromise = _interopRequireDefault(require('./fsPromise'));}var _nuclideUri;function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('./nuclideUri'));}var _promise;function _load_promise() {return _promise = require('./promise');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */if (!(typeof atom !== 'undefined' && atom.inSpecMode() || process.env.NODE_ENV === 'test')) {throw new Error('Test helpers should only be used in spec mode');}function clearRequireCache(require, module) {delete require.cache[require.resolve(module)];}function uncachedRequire(require, module) {clearRequireCache(require, module); // $FlowIgnore + return require(module);} /** + * Jasmine has trouble spying on properties supplied by getters, so to make it + * work we have to get the value, delete the getter, and set the value as a + * property. + * + * This makes two assumptions: + * - The getter is idempotent (otherwise, callers in other tests might be + * surprised when the value here is returned) + * - The getter returns a function (otherwise, it doesn't make sense to spy on + * it) + */function spyOnGetterValue(object, f) {const value = object[f];delete object[f];object[f] = value;return spyOn(object, f);} /** + * Checks if the two objects have equal properties. This considers a property + * set to undefined to be equivalent to a property that was not set at all. + */function arePropertiesEqual(obj1, obj2) {const allProps = new Set();function addAllProps(obj) {for (const prop of Object.keys(obj)) {allProps.add(prop);}}[obj1, obj2].forEach(addAllProps);for (const prop of allProps) {if (obj1[prop] !== obj2[prop]) {return false;}}return true;}function writeCoverage() {const { COVERAGE_DIR } = process.env;if (COVERAGE_DIR != null) {const coverage = global.__coverage__;if (coverage != null) {_fs.default.writeFileSync((_nuclideUri || _load_nuclideUri()).default.join(COVERAGE_DIR, (_uuid || _load_uuid()).default.v4() + '.json'), JSON.stringify(coverage));}}} \ No newline at end of file diff --git a/modules/nuclide-commons/tokenized-text.js b/modules/nuclide-commons/tokenized-text.js index 41b8ced0..684436bb 100644 --- a/modules/nuclide-commons/tokenized-text.js +++ b/modules/nuclide-commons/tokenized-text.js @@ -1,69 +1,73 @@ -/** - * 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 - * @format - */ - -export type TokenKind = - | 'keyword' - | 'class-name' - | 'constructor' - | 'method' - | 'param' - | 'string' - | 'whitespace' - | 'plain' - | 'type'; - -export type TextToken = { - kind: TokenKind, - value: string, -}; - -export type TokenizedText = Array; - -export function keyword(value: string): TextToken { - return _buildToken('keyword', value); -} - -export function className(value: string): TextToken { - return _buildToken('class-name', value); -} - -export function constructor(value: string): TextToken { - return _buildToken('constructor', value); -} - -export function method(value: string): TextToken { - return _buildToken('method', value); -} - -export function param(value: string): TextToken { - return _buildToken('param', value); -} - -export function string(value: string): TextToken { - return _buildToken('string', value); -} - -export function whitespace(value: string): TextToken { - return _buildToken('whitespace', value); -} - -export function plain(value: string): TextToken { - return _buildToken('plain', value); -} - -export function type(value: string): TextToken { - return _buildToken('type', value); -} - -function _buildToken(kind: TokenKind, value: string): TextToken { - return {kind, value}; -} +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +keyword = keyword;exports. + + + +className = className;exports. + + + +constructor = constructor;exports. + + + +method = method;exports. + + + +param = param;exports. + + + +string = string;exports. + + + +whitespace = whitespace;exports. + + + +plain = plain;exports. + + + +type = type;function keyword(value) {return _buildToken('keyword', value);} /** + * 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. + * + * + * @format + */function className(value) {return _buildToken('class-name', value);}function constructor(value) {return _buildToken('constructor', value);}function method(value) {return _buildToken('method', value);}function param(value) {return _buildToken('param', value);}function string(value) {return _buildToken('string', value);}function whitespace(value) {return _buildToken('whitespace', value);}function plain(value) {return _buildToken('plain', value);}function type(value) {return _buildToken('type', value);}function _buildToken(kind, value) {return { kind, value };} \ No newline at end of file diff --git a/modules/nuclide-commons/which.js b/modules/nuclide-commons/which.js index abd320e7..f8d7dfad 100644 --- a/modules/nuclide-commons/which.js +++ b/modules/nuclide-commons/which.js @@ -1,44 +1,44 @@ -/** - * 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 - * @format - */ - -import os from 'os'; -import nuclideUri from './nuclideUri'; - -import {runCommand} from './process'; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + + + + + + + + + + + +var _os = _interopRequireDefault(require('os'));var _nuclideUri; +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('./nuclideUri'));}var _process; + +function _load_process() {return _process = require('./process');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** - * Provides a cross-platform way to check whether a binary is available. - * - * We ran into problems with the npm `which` package (the nature of which I unfortunately don't - * remember) so we can use this for now. - */ - -function sanitizePathForWindows(path: string): string { - if (nuclideUri.basename(path) === path) { + * Provides a cross-platform way to check whether a binary is available. + * + * We ran into problems with the npm `which` package (the nature of which I unfortunately don't + * remember) so we can use this for now. + */ + +function sanitizePathForWindows(path) { + if ((_nuclideUri || _load_nuclideUri()).default.basename(path) === path) { // simple binary in $PATH like `flow` return path; } else { - return `${nuclideUri.dirname(path)}:${nuclideUri.basename(path)}`; - } -} - -export default (async function which(path: string): Promise { - const isWindows = process.platform === 'win32'; - const whichCommand = isWindows ? 'where' : 'which'; - const searchPath = isWindows ? sanitizePathForWindows(path) : path; - try { - const result = await runCommand(whichCommand, [searchPath]).toPromise(); - return result.split(os.EOL)[0]; - } catch (e) { - return null; + return `${(_nuclideUri || _load_nuclideUri()).default.dirname(path)}:${(_nuclideUri || _load_nuclideUri()).default.basename(path)}`; } -}); +} /** + * 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. + * + * + * @format + */exports.default = (() => {var _ref = (0, _asyncToGenerator.default)(function* (path) {const isWindows = process.platform === 'win32';const whichCommand = isWindows ? 'where' : 'which';const searchPath = isWindows ? sanitizePathForWindows(path) : path;try {const result = yield (0, (_process || _load_process()).runCommand)(whichCommand, [searchPath]).toPromise();return result.split(_os.default.EOL)[0];} catch (e) {return null; + } + });function which(_x) {return _ref.apply(this, arguments);}return which;})(); \ No newline at end of file diff --git a/modules/nuclide-debugger-common/AutoGenLaunchAttachProvider.js b/modules/nuclide-debugger-common/AutoGenLaunchAttachProvider.js index 974e7b41..8d385631 100644 --- a/modules/nuclide-debugger-common/AutoGenLaunchAttachProvider.js +++ b/modules/nuclide-debugger-common/AutoGenLaunchAttachProvider.js @@ -1,80 +1,79 @@ -/** - * 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 - * @format - */ - -import type {DebuggerConfigAction} from './types'; -import type {LaunchAttachProviderIsEnabled, AutoGenConfig} from './types'; - -import invariant from 'assert'; -import DebuggerLaunchAttachProvider from './DebuggerLaunchAttachProvider'; -import * as React from 'react'; -import AutoGenLaunchAttachUiComponent from './AutoGenLaunchAttachUiComponent'; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _DebuggerLaunchAttachProvider; + + + + + + + + + + + + + + + +function _load_DebuggerLaunchAttachProvider() {return _DebuggerLaunchAttachProvider = _interopRequireDefault(require('./DebuggerLaunchAttachProvider'));} +var _react = _interopRequireWildcard(require('react'));var _AutoGenLaunchAttachUiComponent; +function _load_AutoGenLaunchAttachUiComponent() {return _AutoGenLaunchAttachUiComponent = _interopRequireDefault(require('./AutoGenLaunchAttachUiComponent'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} const LaunchAttachProviderDefaultIsEnabled = ( - action: DebuggerConfigAction, - config: AutoGenConfig, -) => { +action, +config) => +{ return Promise.resolve(config[action] != null); -}; - -export default class AutoGenLaunchAttachProvider extends DebuggerLaunchAttachProvider { - _config: AutoGenConfig; - _isEnabled: LaunchAttachProviderIsEnabled; - - constructor( - debuggingTypeName: string, - targetUri: string, - config: AutoGenConfig, - isEnabled?: LaunchAttachProviderIsEnabled = LaunchAttachProviderDefaultIsEnabled, - ) { +}; /** + * 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. + * + * + * @format + */class AutoGenLaunchAttachProvider extends (_DebuggerLaunchAttachProvider || _load_DebuggerLaunchAttachProvider()).default {constructor(debuggingTypeName, targetUri, config, isEnabled = LaunchAttachProviderDefaultIsEnabled) + { super(debuggingTypeName, targetUri); this._config = config; this._isEnabled = isEnabled; } - getCallbacksForAction(action: DebuggerConfigAction) { + getCallbacksForAction(action) {var _this = this; return { /** - * Whether this provider is enabled or not. - */ - isEnabled: async (): Promise => { - return this._isEnabled(action, this._config); - }, + * Whether this provider is enabled or not. + */ + isEnabled: (() => {var _ref = (0, _asyncToGenerator.default)(function* () { + return _this._isEnabled(action, _this._config); + });return function isEnabled() {return _ref.apply(this, arguments);};})(), /** - * Returns a list of supported debugger types + environments for the specified action. - */ - getDebuggerTypeNames: super.getCallbacksForAction(action) - .getDebuggerTypeNames, + * Returns a list of supported debugger types + environments for the specified action. + */ + getDebuggerTypeNames: super.getCallbacksForAction(action). + getDebuggerTypeNames, /** - * Returns the UI component for configuring the specified debugger type and action. - */ + * Returns the UI component for configuring the specified debugger type and action. + */ getComponent: ( - debuggerTypeName: string, - configIsValidChanged: (valid: boolean) => void, - ) => { - const launchOrAttachConfig = this._config[action]; - invariant(launchOrAttachConfig != null); + debuggerTypeName, + configIsValidChanged) => + { + const launchOrAttachConfig = this._config[action];if (!( + launchOrAttachConfig != null)) {throw new Error('Invariant violation: "launchOrAttachConfig != null"');} return ( - - ); - }, - }; + _react.createElement((_AutoGenLaunchAttachUiComponent || _load_AutoGenLaunchAttachUiComponent()).default, { + targetUri: this.getTargetUri(), + configIsValidChanged: configIsValidChanged, + config: launchOrAttachConfig, + debuggerTypeName: debuggerTypeName })); + + + } }; + } - dispose(): void {} -} + dispose() {}}exports.default = AutoGenLaunchAttachProvider; \ No newline at end of file diff --git a/modules/nuclide-debugger-common/AutoGenLaunchAttachUiComponent.js b/modules/nuclide-debugger-common/AutoGenLaunchAttachUiComponent.js index 582f628e..041fdae5 100644 --- a/modules/nuclide-debugger-common/AutoGenLaunchAttachUiComponent.js +++ b/modules/nuclide-debugger-common/AutoGenLaunchAttachUiComponent.js @@ -1,3 +1,54 @@ +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + + + + + + + + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react'));var _idx; + +function _load_idx() {return _idx = _interopRequireDefault(require('idx'));}var _nullthrows; +function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));}var _Checkbox; +function _load_Checkbox() {return _Checkbox = require('nuclide-commons-ui/Checkbox');}var _RadioGroup; +function _load_RadioGroup() {return _RadioGroup = _interopRequireDefault(require('nuclide-commons-ui/RadioGroup'));}var _AtomInput; +function _load_AtomInput() {return _AtomInput = require('nuclide-commons-ui/AtomInput');}var _nuclideUri; +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));}var _string; +function _load_string() {return _string = require('nuclide-commons/string');}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));}var _debugger; +function _load_debugger() {return _debugger = require('nuclide-commons-atom/debugger');}var _DebuggerConfigSerializer; +function _load_DebuggerConfigSerializer() {return _DebuggerConfigSerializer = require('./DebuggerConfigSerializer');}var _SelectableFilterableProcessTable; + + + +function _load_SelectableFilterableProcessTable() {return _SelectableFilterableProcessTable = _interopRequireDefault(require('./SelectableFilterableProcessTable'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + + + + + + + + + + + + + + + +// extension must be a string starting with a '.' like '.js' or '.py' /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,401 +57,350 @@ * 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 + * * @format - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type { - AutoGenProperty, - AutoGenLaunchOrAttachConfig, - AutoGenPropertyType, - AutoGenPropertyPrimitiveType, -} from './types'; -import * as React from 'react'; - -import idx from 'idx'; -import nullthrows from 'nullthrows'; -import {Checkbox} from 'nuclide-commons-ui/Checkbox'; -import RadioGroup from 'nuclide-commons-ui/RadioGroup'; -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import {capitalize, shellParse} from 'nuclide-commons/string'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {getDebuggerService} from 'nuclide-commons-atom/debugger'; -import { - serializeDebuggerConfig, - deserializeDebuggerConfig, -} from './DebuggerConfigSerializer'; -import SelectableFilterableProcessTable from './SelectableFilterableProcessTable'; - -type Props = {| - +targetUri: NuclideUri, - +configIsValidChanged: (valid: boolean) => void, - +config: AutoGenLaunchOrAttachConfig, - +debuggerTypeName: string, -|}; - -type State = { - enumValues: Map, - booleanValues: Map, - atomInputValues: Map, - processTableValues: Map, -}; - -// extension must be a string starting with a '.' like '.js' or '.py' -function getActiveScriptPath(extension: string): string { - const center = atom.workspace.getCenter - ? atom.workspace.getCenter() - : atom.workspace; - const activeEditor: ?atom$TextEditor = center.getActiveTextEditor(); - if ( - activeEditor == null || - !activeEditor.getPath() || - !nullthrows(activeEditor.getPath()).endsWith(extension) - ) { - return ''; + */function getActiveScriptPath(extension) {const center = atom.workspace.getCenter ? atom.workspace.getCenter() : atom.workspace;const activeEditor = center.getActiveTextEditor();if (activeEditor == null || !activeEditor.getPath() || !(0, (_nullthrows || _load_nullthrows()).default)(activeEditor.getPath()).endsWith(extension)) {return ''; } - return nuclideUri.getPath(nullthrows(activeEditor.getPath())); + return (_nuclideUri || _load_nuclideUri()).default.getPath((0, (_nullthrows || _load_nullthrows()).default)(activeEditor.getPath())); } -export default class AutoGenLaunchAttachUiComponent extends React.Component< - Props, - State, -> { - _disposables: UniversalDisposable; - - constructor(props: Props) { - super(props); - this._disposables = new UniversalDisposable(); - this.state = { - atomInputValues: new Map(), - booleanValues: new Map(), - enumValues: new Map(), - processTableValues: new Map(), - }; - } +class AutoGenLaunchAttachUiComponent extends _react.Component - _atomInputType( - type: AutoGenPropertyType, - itemType: ?AutoGenPropertyPrimitiveType, - ): boolean { - return ( - type === 'string' || - (type === 'array' && itemType === 'string') || - type === 'object' || - type === 'number' || - type === 'json' - ); - } - _getConfigurationProperties(): AutoGenProperty[] { - const {config} = this.props; - return config.properties; - } +{ - _populateDefaultValues( - config: AutoGenLaunchOrAttachConfig, - atomInputValues: Map, - booleanValues: Map, - enumValues: Map, - ): void { - config.properties.filter(property => property.visible).map(property => { - const {name, type} = property; - const itemType = idx(property, _ => _.itemType); - if (this._atomInputType(type, itemType)) { - const existingValue = atomInputValues.get(name); - if ( - existingValue == null && - typeof property.defaultValue !== 'undefined' - ) { - // String(propertyDescription.default) deals with both strings and numbers and arrays - // JSON.stringify for JSON - // empty string otherwise - const defaultValue = - type === 'string' || type === 'number' || type === 'array' - ? String(property.defaultValue) - : type === 'json' - ? JSON.stringify(property.defaultValue) - : ''; - atomInputValues.set(name, defaultValue); - } - } else if (type === 'boolean') { - const existingValue = booleanValues.get(name); - if ( - existingValue == null && - typeof property.defaultValue !== 'undefined' && - property.defaultValue != null && - typeof property.defaultValue === 'boolean' - ) { - booleanValues.set(name, property.defaultValue); - } else { - booleanValues.set(name, false); - } - } else if (type === 'enum' && property.enums != null) { - const existingValue = enumValues.get(name); - if ( - existingValue == null && - typeof property.defaultValue !== 'undefined' && - property.defaultValue != null && - typeof property.defaultValue === 'string' - ) { - enumValues.set(name, property.defaultValue); - } - } - }); - } - _getSerializationArgs(props: Props) { - const {targetUri, config, debuggerTypeName} = props; - const args = [ - nuclideUri.isRemote(targetUri) - ? nuclideUri.getHostname(targetUri) - : 'local', - config.launch ? 'launch' : 'attach', - debuggerTypeName, - ]; - return args; - } + constructor(props) {var _this; + _this = super(props);this. - _deserializeDebuggerConfig(props: Props): void { - deserializeDebuggerConfig( - ...this._getSerializationArgs(props), - (transientSettings, savedSettings) => { - const {config} = props; - const { - cwdPropertyName, - scriptPropertyName, - launch, - scriptExtension, - } = config; - const atomInputValues = new Map(savedSettings.atomInputValues || []); - - const scriptPath = - (scriptPropertyName != null && - atomInputValues.get(scriptPropertyName)) || - (scriptExtension != null && getActiveScriptPath(scriptExtension)) || - ''; - if (cwdPropertyName != null) { - const cwd = - atomInputValues.get(cwdPropertyName) || - (scriptPath !== '' ? nuclideUri.dirname(scriptPath) : ''); - if (cwd !== '') { - atomInputValues.set(cwdPropertyName, cwd); - } - } - if (launch) { - if (scriptPath !== '' && scriptPropertyName != null) { - atomInputValues.set(scriptPropertyName, scriptPath); - } - } - const booleanValues = new Map(savedSettings.booleanValues || []); - const enumValues = new Map(savedSettings.enumValues || []); - this._populateDefaultValues( - config, - atomInputValues, - booleanValues, - enumValues, - ); - // do not serialize and deserialize processes - const processTableValues = new Map(); - this.setState({ - atomInputValues, - booleanValues, - enumValues, - processTableValues, - }); - }, - ); - } - setState(newState: Object): void { - super.setState(newState, () => - this.props.configIsValidChanged(this._debugButtonShouldEnable()), - ); - } - componentWillReceiveProps(nextProps: Props) { - if (nextProps.debuggerTypeName !== this.props.debuggerTypeName) { - this._deserializeDebuggerConfig(nextProps); - } - } - componentWillMount(): void { - this._deserializeDebuggerConfig(this.props); - } - componentDidMount(): void { - this._disposables.add( - atom.commands.add('atom-workspace', { - 'core:confirm': async () => { - if (this._debugButtonShouldEnable()) { - await this._handleDebugButtonClick(); - } - }, - }), - ); - } - componentWillUnmount(): void { - this._disposables.dispose(); - } - _valueExists(property: AutoGenProperty): boolean { - const {name, type} = property; - if (type === 'string') { - const value = this.state.atomInputValues.get(name); - return value != null && value !== ''; - } else if (type === 'number') { - const value = this.state.atomInputValues.get(name); - return value != null && !isNaN(value); - } else if (type === 'boolean') { - const value = this.state.booleanValues.get(name); - return value != null; - } else if (type === 'enum') { - const value = this.state.enumValues.get(name); - return value != null; - } else if (type === 'process') { - const value = this.state.processTableValues.get(name); - return value != null; - } - return false; - } - _debugButtonShouldEnable(): boolean { - return this._getConfigurationProperties() - .filter(p => p.required) - .every(p => this._valueExists(p)); - } - _getComponentForProperty(property: AutoGenProperty): React.Node { - const {name, type, description, required} = property; - const formattedName = - capitalize(name.replace(/([A-Z])/g, ' $1')) + - (required ? ' (Required)' : ''); - const nameLabel = ; - const itemType = idx(property, _ => _.itemType); - if (this._atomInputType(type, itemType)) { - const value = this.state.atomInputValues.get(name) || ''; - return ( -
      - {nameLabel} - { - this.state.atomInputValues.set(name, newValue); - this.props.configIsValidChanged(this._debugButtonShouldEnable()); - }} - /> -
      - ); - } else if (type === 'boolean') { - const checked = this.state.booleanValues.get(name) || false; - return ( -
      -
      {nameLabel}
      - { - this.state.booleanValues.set(name, newValue); - this.props.configIsValidChanged(this._debugButtonShouldEnable()); - }} - /> -
      - ); - } else if (type === 'enum' && property.enums != null) { - const enums = property.enums; - const selectedValue = this.state.enumValues.get(name) || ''; - return ( -
      - {nameLabel} - ( - - ))} - onSelectedChange={index => { - this.state.enumValues.set(name, enums[index]); - this.props.configIsValidChanged(this._debugButtonShouldEnable()); - }} - /> -
      - ); - } else if (type === 'process') { - return ( -
      - {nameLabel} - { - if (selectedProcess != null) { - this.state.processTableValues.set(name, selectedProcess.pid); - } else { - this.state.processTableValues.delete(name); - } - this.props.configIsValidChanged(this._debugButtonShouldEnable()); - }} - /> -
      - ); - } - return ( -
      - -
      -
      - ); - } - render(): React.Node { - const {debuggerTypeName, config} = this.props; - return ( -
      - {config.header} - {this._getConfigurationProperties() - .filter(property => property.visible) - .map(property => ( -
      - {this._getComponentForProperty(property)} -
      - ))} -
      - ); - } - _handleDebugButtonClick = async (): Promise => { - const {targetUri, config} = this.props; - const { - atomInputValues, - booleanValues, - enumValues, - processTableValues, - } = this.state; - const {launch, vsAdapterType, threads} = config; - - const stringValues = new Map(); - const stringArrayValues = new Map(); - const objectValues = new Map(); - const numberValues = new Map(); - const jsonValues = new Map(); - this._getConfigurationProperties() - .filter( - property => property.visible && atomInputValues.has(property.name), - ) - .forEach(property => { - const {name, type} = property; - const itemType = idx(property, _ => _.itemType); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _handleDebugButtonClick = (0, _asyncToGenerator.default)(function* () { + const { targetUri, config } = _this.props; + const { + atomInputValues, + booleanValues, + enumValues, + processTableValues } = + _this.state; + const { launch, vsAdapterType, threads } = config; + + const stringValues = new Map(); + const stringArrayValues = new Map(); + const objectValues = new Map(); + const numberValues = new Map(); + const jsonValues = new Map(); + _this._getConfigurationProperties(). + filter( + function (property) {return property.visible && atomInputValues.has(property.name);}). + + forEach(function (property) {var _ref3; + const { name, type } = property; + const itemType = (_ref3 = property) != null ? _ref3.itemType : _ref3; const value = atomInputValues.get(name) || ''; if (type === 'string') { stringValues.set(name, value); } else if (type === 'array' && itemType === 'string') { - stringArrayValues.set(name, shellParse(value)); + stringArrayValues.set(name, (0, (_string || _load_string()).shellParse)(value)); } else if (type === 'object') { const objectValue = {}; - shellParse(value).forEach(variable => { + (0, (_string || _load_string()).shellParse)(value).forEach(function (variable) { const [lhs, rhs] = variable.split('='); objectValue[lhs] = rhs; }); @@ -412,8 +412,8 @@ export default class AutoGenLaunchAttachUiComponent extends React.Component< } }); - const values = {}; - [ + const values = {}; + [ booleanValues, enumValues, stringValues, @@ -421,40 +421,43 @@ export default class AutoGenLaunchAttachUiComponent extends React.Component< objectValues, numberValues, processTableValues, - jsonValues, - ].forEach(map => { - map.forEach((value, key) => { - values[key] = value; + jsonValues]. + forEach(function (map) { + map.forEach(function (value, key) { + values[key] = value; + }); }); - }); - - this._getConfigurationProperties() - .filter( - property => !property.visible && !atomInputValues.has(property.name), - ) - .forEach(property => { - const {name} = property; - values[name] = idx(property, _ => _.defaultValue); + + _this._getConfigurationProperties(). + filter( + function (property) {return !property.visible && !atomInputValues.has(property.name);}). + + forEach(function (property) {var _ref4; + const { name } = property; + values[name] = (_ref4 = property) != null ? _ref4.defaultValue : _ref4; }); - const debuggerService = await getDebuggerService(); - debuggerService.startVspDebugging({ - targetUri, - debugMode: launch ? 'launch' : 'attach', - adapterType: vsAdapterType, - adapterExecutable: null, - config: values, - capabilities: {threads}, - properties: { - customControlButtons: [], - threadsComponentTitle: 'Threads', - }, - }); - - serializeDebuggerConfig(...this._getSerializationArgs(this.props), { - atomInputValues: Array.from(atomInputValues), - booleanValues: Array.from(booleanValues), - enumValues: Array.from(enumValues), - }); - }; -} + const debuggerService = yield (0, (_debugger || _load_debugger()).getDebuggerService)(); + debuggerService.startVspDebugging({ + targetUri, + debugMode: launch ? 'launch' : 'attach', + adapterType: vsAdapterType, + adapterExecutable: null, + config: values, + capabilities: { threads }, + properties: { + customControlButtons: [], + threadsComponentTitle: 'Threads' } }); + + + + (0, (_DebuggerConfigSerializer || _load_DebuggerConfigSerializer()).serializeDebuggerConfig)(..._this._getSerializationArgs(_this.props), { + atomInputValues: Array.from(atomInputValues), + booleanValues: Array.from(booleanValues), + enumValues: Array.from(enumValues) }); + + });this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default();this.state = { atomInputValues: new Map(), booleanValues: new Map(), enumValues: new Map(), processTableValues: new Map() };}_atomInputType(type, itemType) {return type === 'string' || type === 'array' && itemType === 'string' || type === 'object' || type === 'number' || type === 'json';}_getConfigurationProperties() {const { config } = this.props;return config.properties;}_populateDefaultValues(config, atomInputValues, booleanValues, enumValues) {config.properties.filter(property => property.visible).map(property => {var _ref;const { name, type } = property;const itemType = (_ref = property) != null ? _ref.itemType : _ref;if (this._atomInputType(type, itemType)) {const existingValue = atomInputValues.get(name);if (existingValue == null && typeof property.defaultValue !== 'undefined') {// String(propertyDescription.default) deals with both strings and numbers and arrays + // JSON.stringify for JSON + // empty string otherwise + const defaultValue = type === 'string' || type === 'number' || type === 'array' ? String(property.defaultValue) : type === 'json' ? JSON.stringify(property.defaultValue) : '';atomInputValues.set(name, defaultValue);}} else if (type === 'boolean') {const existingValue = booleanValues.get(name);if (existingValue == null && typeof property.defaultValue !== 'undefined' && property.defaultValue != null && typeof property.defaultValue === 'boolean') {booleanValues.set(name, property.defaultValue);} else {booleanValues.set(name, false);}} else if (type === 'enum' && property.enums != null) {const existingValue = enumValues.get(name);if (existingValue == null && typeof property.defaultValue !== 'undefined' && property.defaultValue != null && typeof property.defaultValue === 'string') {enumValues.set(name, property.defaultValue);}}});}_getSerializationArgs(props) {const { targetUri, config, debuggerTypeName } = props;const args = [(_nuclideUri || _load_nuclideUri()).default.isRemote(targetUri) ? (_nuclideUri || _load_nuclideUri()).default.getHostname(targetUri) : 'local', config.launch ? 'launch' : 'attach', debuggerTypeName];return args;}_deserializeDebuggerConfig(props) {(0, (_DebuggerConfigSerializer || _load_DebuggerConfigSerializer()).deserializeDebuggerConfig)(...this._getSerializationArgs(props), (transientSettings, savedSettings) => {const { config } = props;const { cwdPropertyName, scriptPropertyName, launch, scriptExtension } = config;const atomInputValues = new Map(savedSettings.atomInputValues || []);const scriptPath = scriptPropertyName != null && atomInputValues.get(scriptPropertyName) || scriptExtension != null && getActiveScriptPath(scriptExtension) || '';if (cwdPropertyName != null) {const cwd = atomInputValues.get(cwdPropertyName) || (scriptPath !== '' ? (_nuclideUri || _load_nuclideUri()).default.dirname(scriptPath) : '');if (cwd !== '') {atomInputValues.set(cwdPropertyName, cwd);}}if (launch) {if (scriptPath !== '' && scriptPropertyName != null) {atomInputValues.set(scriptPropertyName, scriptPath);}}const booleanValues = new Map(savedSettings.booleanValues || []);const enumValues = new Map(savedSettings.enumValues || []);this._populateDefaultValues(config, atomInputValues, booleanValues, enumValues); // do not serialize and deserialize processes + const processTableValues = new Map();this.setState({ atomInputValues, booleanValues, enumValues, processTableValues });});}setState(newState) {super.setState(newState, () => this.props.configIsValidChanged(this._debugButtonShouldEnable()));}componentWillReceiveProps(nextProps) {if (nextProps.debuggerTypeName !== this.props.debuggerTypeName) {this._deserializeDebuggerConfig(nextProps);}}componentWillMount() {this._deserializeDebuggerConfig(this.props);}componentDidMount() {var _this2 = this;this._disposables.add(atom.commands.add('atom-workspace', { 'core:confirm': (() => {var _ref6 = (0, _asyncToGenerator.default)(function* () {if (_this2._debugButtonShouldEnable()) {yield _this2._handleDebugButtonClick();}});return function coreConfirm() {return _ref6.apply(this, arguments);};})() }));}componentWillUnmount() {this._disposables.dispose();}_valueExists(property) {const { name, type } = property;if (type === 'string') {const value = this.state.atomInputValues.get(name);return value != null && value !== '';} else if (type === 'number') {const value = this.state.atomInputValues.get(name);return value != null && !isNaN(value);} else if (type === 'boolean') {const value = this.state.booleanValues.get(name);return value != null;} else if (type === 'enum') {const value = this.state.enumValues.get(name);return value != null;} else if (type === 'process') {const value = this.state.processTableValues.get(name);return value != null;}return false;}_debugButtonShouldEnable() {return this._getConfigurationProperties().filter(p => p.required).every(p => this._valueExists(p));}_getComponentForProperty(property) {var _ref2;const { name, type, description, required } = property;const formattedName = (0, (_string || _load_string()).capitalize)(name.replace(/([A-Z])/g, ' $1')) + (required ? ' (Required)' : '');const nameLabel = _react.createElement('label', null, formattedName, ':');const itemType = (_ref2 = property) != null ? _ref2.itemType : _ref2;if (this._atomInputType(type, itemType)) {const value = this.state.atomInputValues.get(name) || '';return _react.createElement('div', null, nameLabel, _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { key: this.props.debuggerTypeName + ':' + name, placeholderText: description, value: value, onDidChange: newValue => {this.state.atomInputValues.set(name, newValue);this.props.configIsValidChanged(this._debugButtonShouldEnable());} }));} else if (type === 'boolean') {const checked = this.state.booleanValues.get(name) || false;return _react.createElement('div', null, _react.createElement('div', null, nameLabel), _react.createElement((_Checkbox || _load_Checkbox()).Checkbox, { checked: checked, label: description, onChange: newValue => {this.state.booleanValues.set(name, newValue);this.props.configIsValidChanged(this._debugButtonShouldEnable());} }));} else if (type === 'enum' && property.enums != null) {const enums = property.enums;const selectedValue = this.state.enumValues.get(name) || '';return _react.createElement('div', null, nameLabel, _react.createElement((_RadioGroup || _load_RadioGroup()).default, { selectedIndex: enums.indexOf(selectedValue), optionLabels: enums.map((enumValue, i) => _react.createElement('label', { key: i }, enumValue)), onSelectedChange: index => {this.state.enumValues.set(name, enums[index]);this.props.configIsValidChanged(this._debugButtonShouldEnable());} }));} else if (type === 'process') {return _react.createElement('div', null, nameLabel, _react.createElement((_SelectableFilterableProcessTable || _load_SelectableFilterableProcessTable()).default, { targetUri: this.props.targetUri, onSelect: selectedProcess => {if (selectedProcess != null) {this.state.processTableValues.set(name, selectedProcess.pid);} else {this.state.processTableValues.delete(name);}this.props.configIsValidChanged(this._debugButtonShouldEnable());} }));}return _react.createElement('div', null, _react.createElement('label', null, 'NO TRANSLATION YET FOR: ', (0, (_string || _load_string()).capitalize)(name)), _react.createElement('hr', null));}render() {const { debuggerTypeName, config } = this.props;return _react.createElement('div', { className: 'block' }, config.header, this._getConfigurationProperties().filter(property => property.visible).map(property => _react.createElement('div', { key: debuggerTypeName + ':' + property.name }, this._getComponentForProperty(property))));}}exports.default = AutoGenLaunchAttachUiComponent; \ No newline at end of file diff --git a/modules/nuclide-debugger-common/DebuggerConfigSerializer.js b/modules/nuclide-debugger-common/DebuggerConfigSerializer.js index 954c186b..7fc6c053 100644 --- a/modules/nuclide-debugger-common/DebuggerConfigSerializer.js +++ b/modules/nuclide-debugger-common/DebuggerConfigSerializer.js @@ -1,64 +1,64 @@ -/** - * 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 - * @format - */ -/* global localStorage */ - -import type {DebuggerConfigAction} from './types'; - -// transientSettings will matinain configuration that should be persisted for the +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + +serializeDebuggerConfig = serializeDebuggerConfig;exports. + + + + + + + + + + + + + + + + + + + +deserializeDebuggerConfig = deserializeDebuggerConfig; // transientSettings will matinain configuration that should be persisted for the // duration of the current Nunclide session (so preserved across the configuration dialog // closing and re-opening), but not preserved if Nuclide is restarted. -const transientSettings = {}; - -function _getStorageKey( - host: string, - action: DebuggerConfigAction, - debuggerName: string, -) { - return 'NUCLIDE_DEBUGGER_CONFIG_' + host + '_' + action + '_' + debuggerName; -} - -export function serializeDebuggerConfig( - host: string, - action: DebuggerConfigAction, - debuggerName: string, - persistent: Object, - transient?: Object, -): void { - if (global.localStorage == null) { - throw new Error('localStorage is not available in this runtime'); - } - const key = _getStorageKey(host, action, debuggerName); - localStorage.setItem(key, JSON.stringify(persistent)); - - if (transient == null) { - delete transientSettings[key]; - } else { - transientSettings[key] = transient; - } -} - -export function deserializeDebuggerConfig( - host: string, - action: DebuggerConfigAction, - debuggerName: string, - callback: (transientSettings: Object, persistentSettings: Object) => void, -): void { - if (global.localStorage == null) { - throw new Error('localStorage is not available in this runtime'); - } - const key = _getStorageKey(host, action, debuggerName); - const val = localStorage.getItem(key); - try { - const persistedSettings = val != null ? (JSON.parse(val): any) : {}; - callback(transientSettings[key] || {}, persistedSettings); +const transientSettings = {}; /** + * 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. + * + * + * @format + */ /* global localStorage */function _getStorageKey(host, action, debuggerName) {return 'NUCLIDE_DEBUGGER_CONFIG_' + host + '_' + action + '_' + debuggerName;}function serializeDebuggerConfig(host, action, debuggerName, persistent, transient) {if (global.localStorage == null) {throw new Error('localStorage is not available in this runtime');}const key = _getStorageKey(host, action, debuggerName);localStorage.setItem(key, JSON.stringify(persistent));if (transient == null) {delete transientSettings[key];} else {transientSettings[key] = transient;}}function deserializeDebuggerConfig(host, action, debuggerName, callback) {if (global.localStorage == null) {throw new Error('localStorage is not available in this runtime');}const key = _getStorageKey(host, action, debuggerName);const val = localStorage.getItem(key);try {const persistedSettings = val != null ? JSON.parse(val) : {};callback(transientSettings[key] || {}, persistedSettings); } catch (err) {} -} +} \ No newline at end of file diff --git a/modules/nuclide-debugger-common/DebuggerLaunchAttachProvider.js b/modules/nuclide-debugger-common/DebuggerLaunchAttachProvider.js index dcf632d0..7e19c963 100644 --- a/modules/nuclide-debugger-common/DebuggerLaunchAttachProvider.js +++ b/modules/nuclide-debugger-common/DebuggerLaunchAttachProvider.js @@ -1,91 +1,90 @@ -/** - * 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 - * @format - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {DebuggerConfigAction} from './types'; -import * as React from 'react'; - -let uniqueKeySeed = 0; - -export type callbacksForAction = { - isEnabled: () => Promise, - getDebuggerTypeNames: () => Array, - getComponent: ( - debuggerTypeName: string, - configIsValidChanged: (valid: boolean) => void, - ) => ?React.Element, -}; +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); + + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react'));function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} + +let uniqueKeySeed = 0; /** + * 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. + * + * + * @format + */ /** - * Base class of all launch/attach providers. - * It allows each concrete provider to provide customized debugging types, actions and UI. - */ -export default class DebuggerLaunchAttachProvider { - _debuggingTypeName: string; - _targetUri: NuclideUri; - _uniqueKey: number; - - constructor(debuggingTypeName: string, targetUri: NuclideUri) { + * Base class of all launch/attach providers. + * It allows each concrete provider to provide customized debugging types, actions and UI. + */ +class DebuggerLaunchAttachProvider { + + + + + constructor(debuggingTypeName, targetUri) { this._debuggingTypeName = debuggingTypeName; this._targetUri = targetUri; this._uniqueKey = uniqueKeySeed++; } - getCallbacksForAction(action: DebuggerConfigAction): callbacksForAction { + getCallbacksForAction(action) { return { /** - * Whether this provider is enabled or not. - */ + * Whether this provider is enabled or not. + */ isEnabled: () => { return Promise.resolve(true); }, /** - * Returns a list of supported debugger types + environments for the specified action. - */ + * Returns a list of supported debugger types + environments for the specified action. + */ getDebuggerTypeNames: () => { return [this._debuggingTypeName]; }, /** - * Returns the UI component for configuring the specified debugger type and action. - */ + * Returns the UI component for configuring the specified debugger type and action. + */ getComponent: ( - debuggerTypeName: string, - configIsValidChanged: (valid: boolean) => void, - ) => { + debuggerTypeName, + configIsValidChanged) => + { throw new Error('abstract method'); - }, - }; + } }; + } /** - * Returns a unique key which can be associated with the component. - */ - getUniqueKey(): number { + * Returns a unique key which can be associated with the component. + */ + getUniqueKey() { return this._uniqueKey; } /** - * Returns target uri for this provider. - */ - getTargetUri(): NuclideUri { + * Returns target uri for this provider. + */ + getTargetUri() { return this._targetUri; } /** - * Dispose any resource held by this provider. - */ - dispose(): void { + * Dispose any resource held by this provider. + */ + dispose() { throw new Error('abstract method'); - } -} + }}exports.default = DebuggerLaunchAttachProvider; \ No newline at end of file diff --git a/modules/nuclide-debugger-common/SelectableFilterableProcessTable.js b/modules/nuclide-debugger-common/SelectableFilterableProcessTable.js index 5e2b5935..f5649024 100644 --- a/modules/nuclide-debugger-common/SelectableFilterableProcessTable.js +++ b/modules/nuclide-debugger-common/SelectableFilterableProcessTable.js @@ -1,96 +1,96 @@ -/** - * 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 - * @format - */ - -import type {Column} from 'nuclide-commons-ui/Table'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {ProcessInfo} from 'nuclide-commons/process'; -import * as React from 'react'; - -import {getVSCodeDebuggerAdapterServiceByNuclideUri} from './debug-adapter-service'; -import {AtomInput} from 'nuclide-commons-ui/AtomInput'; -import {Table} from 'nuclide-commons-ui/Table'; -import nuclideUri from 'nuclide-commons/nuclideUri'; -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Observable} from 'rxjs'; - -const PROCESS_UPDATES_INTERVAL_MS = 2000; - -const COLUMNS: Array> = [ - { - title: 'Process Binary', - key: 'process', - width: 0.25, - }, - { - title: 'PID', - key: 'pid', - width: 0.1, - }, - { - title: 'Command', - key: 'command', - width: 0.65, - }, -]; - -type ColumnName = 'process' | 'pid' | 'command'; - -type ProcessRow = { - process: string, - pid: number, - command: string, -}; - -type Props = {| - +targetUri: NuclideUri, - +onSelect?: (selectedProcess: ?ProcessRow) => mixed, -|}; - -type State = { - processList: Array, - selectedProcess: ?ProcessRow, - sortDescending: boolean, - sortedColumn: ?ColumnName, - filterText: string, -}; +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); + + + + + + + + + + + + + + +var _react = _interopRequireWildcard(require('react'));var _debugAdapterService; + +function _load_debugAdapterService() {return _debugAdapterService = require('./debug-adapter-service');}var _AtomInput; +function _load_AtomInput() {return _AtomInput = require('nuclide-commons-ui/AtomInput');}var _Table; +function _load_Table() {return _Table = require('nuclide-commons-ui/Table');}var _nuclideUri; +function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));}var _UniversalDisposable; +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));} +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} /** + * 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. + * + * + * @format + */const PROCESS_UPDATES_INTERVAL_MS = 2000;const COLUMNS = [{ title: 'Process Binary', key: 'process', width: 0.25 }, { + title: 'PID', + key: 'pid', + width: 0.1 }, + +{ + title: 'Command', + key: 'command', + width: 0.65 }]; + + + + + + + + + + + + + + + + + + + + + + + function getCompareFunction( - sortedColumn: ?ColumnName, - sortDescending: boolean, -): (a: ProcessRow, b: ProcessRow) => number { +sortedColumn, +sortDescending) +{ switch (sortedColumn) { case 'process': - return (target1: ProcessRow, target2: ProcessRow) => { + return (target1, target2) => { const first = sortDescending ? target2.process : target1.process; const second = sortDescending ? target1.process : target2.process; return first.toLowerCase().localeCompare(second.toLowerCase()); }; case 'pid': const order = sortDescending ? -1 : 1; - return (target1: ProcessRow, target2: ProcessRow) => - order * (target1.pid - target2.pid); + return (target1, target2) => + order * (target1.pid - target2.pid); case 'command': - return (target1: ProcessRow, target2: ProcessRow) => { + return (target1, target2) => { const first = sortDescending ? target2.command : target1.command; const second = sortDescending ? target1.command : target2.command; return first.toLowerCase().localeCompare(second.toLowerCase()); }; default: - break; - } + break;} + return () => 0; } -function filterProcesses(processes: Array, filterText: string) { +function filterProcesses(processes, filterText) { // Show all results if invalid regex let filterRegex; try { @@ -99,189 +99,188 @@ function filterProcesses(processes: Array, filterText: string) { return processes; } return processes.filter( - item => - filterRegex.test(item.process) || - filterRegex.test(item.pid.toString()) || - filterRegex.test(item.command), - ); + item => + filterRegex.test(item.process) || + filterRegex.test(item.pid.toString()) || + filterRegex.test(item.command)); + } -export default class SelectableFilterableProcessTable extends React.Component< - Props, - State, -> { - _disposables: UniversalDisposable; - - constructor(props: Props) { - super(props); - this._disposables = new UniversalDisposable(); - this.state = { - processList: [], - selectedProcess: null, - sortDescending: false, - sortedColumn: null, - filterText: '', - }; - } +class SelectableFilterableProcessTable extends _react.Component - componentDidMount(): void { - this._disposables.add( - Observable.interval(PROCESS_UPDATES_INTERVAL_MS) - .startWith(0) - .flatMap(_ => - getVSCodeDebuggerAdapterServiceByNuclideUri( - this.props.targetUri, - ).getProcessTree(), - ) - .subscribe(this._updateList), - ); - } - componentWillUnmount() { - this._disposables.dispose(); - } +{ - _updateList = (processes: Array): void => { - // On Linux, process names for which only a name is available - // are denoted as [name] in the commandWithArgs field. These - // names often do not play well with basename (in particular, - // some of the contain literal slashes) so handle them as a special - // case. - const noargsRegex = /^\[(.*)\]$/; - const commandName = (name, withArgs) => { - const match = withArgs.match(noargsRegex); - if (match != null) { - return match[1]; - } - return nuclideUri.basename(name); - }; - - const processList = processes.map(process => { - return { - process: commandName(process.command, process.commandWithArgs), - pid: process.pid, - command: process.commandWithArgs, + + constructor(props) { + super(props);this. + + + + + + + + + + + + + + + + + + + + + + + + + + + + _updateList = processes => { + // On Linux, process names for which only a name is available + // are denoted as [name] in the commandWithArgs field. These + // names often do not play well with basename (in particular, + // some of the contain literal slashes) so handle them as a special + // case. + const noargsRegex = /^\[(.*)\]$/; + const commandName = (name, withArgs) => { + const match = withArgs.match(noargsRegex); + if (match != null) { + return match[1]; + } + return (_nuclideUri || _load_nuclideUri()).default.basename(name); }; - }); - this.setState({processList}); - }; + const processList = processes.map(process => { + return { + process: commandName(process.command, process.commandWithArgs), + pid: process.pid, + command: process.commandWithArgs }; - _handleFilterTextChange = (filterText: string): void => { - // Check if we've filtered down to one option and select if so - const filteredProcesses = filterProcesses( - this.state.processList, - filterText, - ); - let selectedProcess = this.state.selectedProcess; - if (filteredProcesses.length === 1) { + }); + + this.setState({ processList }); + };this. + + _handleFilterTextChange = filterText => { // Check if we've filtered down to one option and select if so - selectedProcess = filteredProcesses[0]; - } else if ( + const filteredProcesses = filterProcesses( + this.state.processList, + filterText); + + let selectedProcess = this.state.selectedProcess; + if (filteredProcesses.length === 1) { + // Check if we've filtered down to one option and select if so + selectedProcess = filteredProcesses[0]; + } else if ( filteredProcesses.findIndex( - processRow => - selectedProcess != null && selectedProcess.pid === processRow.pid, - ) === -1 - ) { - // If we filter out our current selection, - // set our current selection to null - selectedProcess = null; - } - - this.setState({ - filterText, - selectedProcess, - }); - }; - - setState(newState: Object): void { - const onSelect = - this.props.onSelect != null ? this.props.onSelect : _ => {}; - - let changedSelectedProcess = false; - if (newState.selectedProcess != null) { - if (this.state.selectedProcess != null) { - changedSelectedProcess = - newState.selectedProcess.pid !== this.state.selectedProcess.pid; - } else { - changedSelectedProcess = true; + processRow => + selectedProcess != null && selectedProcess.pid === processRow.pid) === + -1) + { + // If we filter out our current selection, + // set our current selection to null + selectedProcess = null; } - } else if (typeof newState.selectedProcess === 'undefined') { - // this is the case that setState was not called with a selectedProcess - changedSelectedProcess = false; - } else { - changedSelectedProcess = this.state.selectedProcess != null; - } - - super.setState(newState, () => { - changedSelectedProcess && onSelect(newState.selectedProcess); - }); - } - _handleSelectTableRow = ( - selectedProcess: ProcessRow, - selectedIndex: number, - ): void => { - this.setState({selectedProcess}); - }; + this.setState({ + filterText, + selectedProcess }); + + };this. + + + + + - _handleSort = (sortedColumn: ColumnName, sortDescending: boolean): void => { - this.setState({ - sortedColumn, - sortDescending, - }); - }; - render(): React.Node { + + + + + + + + + + + + + + + + + + + _handleSelectTableRow = ( + selectedProcess, + selectedIndex) => + { + this.setState({ selectedProcess }); + };this. + + _handleSort = (sortedColumn, sortDescending) => { + this.setState({ + sortedColumn, + sortDescending }); + + };this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default();this.state = { processList: [], selectedProcess: null, sortDescending: false, sortedColumn: null, filterText: '' };}componentDidMount() {this._disposables.add(_rxjsBundlesRxMinJs.Observable.interval(PROCESS_UPDATES_INTERVAL_MS).startWith(0).flatMap(_ => (0, (_debugAdapterService || _load_debugAdapterService()).getVSCodeDebuggerAdapterServiceByNuclideUri)(this.props.targetUri).getProcessTree()).subscribe(this._updateList));}componentWillUnmount() {this._disposables.dispose();}setState(newState) {const onSelect = this.props.onSelect != null ? this.props.onSelect : _ => {};let changedSelectedProcess = false;if (newState.selectedProcess != null) {if (this.state.selectedProcess != null) {changedSelectedProcess = newState.selectedProcess.pid !== this.state.selectedProcess.pid;} else {changedSelectedProcess = true;}} else if (typeof newState.selectedProcess === 'undefined') {// this is the case that setState was not called with a selectedProcess + changedSelectedProcess = false;} else {changedSelectedProcess = this.state.selectedProcess != null;}super.setState(newState, () => {changedSelectedProcess && onSelect(newState.selectedProcess);});} + render() { const { processList, sortedColumn, sortDescending, selectedProcess, - filterText, - } = this.state; + filterText } = + this.state; const sortFunction = getCompareFunction(sortedColumn, sortDescending); let selectedIndex = null; - const rows = filterProcesses(processList, filterText) - .sort(sortFunction) - .map((process, index) => { - const row = { - data: process, - }; + const rows = filterProcesses(processList, filterText). + sort(sortFunction). + map((process, index) => { + const row = { + data: process }; - if (selectedProcess != null && selectedProcess.pid === process.pid) { - selectedIndex = index; - } - return row; - }); + if (selectedProcess != null && selectedProcess.pid === process.pid) { + selectedIndex = index; + } + + return row; + }); return ( -
      -

      Attach to a running native process

      - -
    - - ); - } -} + _react.createElement('div', { className: 'block' }, + _react.createElement('p', null, 'Attach to a running native process'), + _react.createElement((_AtomInput || _load_AtomInput()).AtomInput, { + placeholderText: 'Search...', + value: this.state.filterText, + onDidChange: this._handleFilterTextChange, + size: 'sm', + autofocus: true }), + + _react.createElement((_Table || _load_Table()).Table, { + columns: COLUMNS, + fixedHeader: true, + maxBodyHeight: '30em', + rows: rows, + sortable: true, + onSort: this._handleSort, + sortedColumn: this.state.sortedColumn, + sortDescending: this.state.sortDescending, + selectable: true, + selectedIndex: selectedIndex, + onSelect: this._handleSelectTableRow, + collapsable: true }))); + + + + }}exports.default = SelectableFilterableProcessTable; \ No newline at end of file diff --git a/modules/nuclide-debugger-common/V8Protocol.js b/modules/nuclide-debugger-common/V8Protocol.js index 4cfd95ad..89a60528 100644 --- a/modules/nuclide-debugger-common/V8Protocol.js +++ b/modules/nuclide-debugger-common/V8Protocol.js @@ -1,40 +1,40 @@ -/** - * 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 - * @format - */ - -import type {MessageProcessor} from './types'; -import * as DebugProtocol from 'vscode-debugprotocol'; - -const TWO_CRLF = '\r\n\r\n'; - -/** - * JSON-RPC protocol implementation over a read and write buffers. - */ -export default class V8Protocol { - _id: string; - _output: (input: string) => mixed; - _sequence: number; - _pendingRequests: Map void>; - _rawData: Buffer; - _contentLength: number; - _logger: log4js$Logger; - _sendPreprocessors: MessageProcessor[]; - _receivePreprocessors: MessageProcessor[]; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _vscodeDebugprotocol; + + + + + + + + + + + + +function _load_vscodeDebugprotocol() {return _vscodeDebugprotocol = _interopRequireWildcard(require('vscode-debugprotocol'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */const TWO_CRLF = '\r\n\r\n'; /** + * JSON-RPC protocol implementation over a read and write buffers. + */class V8Protocol { + + + + constructor( - id: string, - logger: log4js$Logger, - sendPreprocessors: MessageProcessor[], - receivePreprocessors: MessageProcessor[], - ) { + id, + logger, + sendPreprocessors, + receivePreprocessors) + { this._id = id; this._logger = logger; this._sendPreprocessors = sendPreprocessors; @@ -45,30 +45,30 @@ export default class V8Protocol { this._rawData = new Buffer(0); } - getId(): string { + getId() { return this._id; } - onServerError(error: Error): void { + onServerError(error) { throw new Error('No implementation found!'); } - onEvent(event: DebugProtocol.Event): void { + onEvent(event) { throw new Error('No implementation found!'); } - async dispatchRequest( - request: DebugProtocol.Request, - response: DebugProtocol.Response, - ): Promise { - throw new Error('No implementation found!'); + dispatchRequest( + request, + response) + {return (0, _asyncToGenerator.default)(function* () { + throw new Error('No implementation found!');})(); } - setOutput(output: (input: string) => mixed): void { + setOutput(output) { this._output = output; } - send(command: string, args: any): Promise { + send(command, args) { return new Promise((resolve, reject) => { this._doSend(command, args, result => { if (result.success) { @@ -80,26 +80,26 @@ export default class V8Protocol { }); } - sendResponse(response: DebugProtocol.Response): void { + sendResponse(response) { if (response.seq > 0) { this._logger.error( - `attempt to send more than one response for command ${ - response.command - }`, - ); + `attempt to send more than one response for command ${ + response.command + }`); + } else { this._sendMessage('response', response); } } _doSend( - command: string, - args: any, - clb: (result: DebugProtocol.Response) => void, - ): void { - const request: any = { - command, - }; + command, + args, + clb) + { + const request = { + command }; + if (args && Object.keys(args).length > 0) { request.arguments = args; } @@ -113,10 +113,10 @@ export default class V8Protocol { } _sendMessage( - typ: 'request' | 'response' | 'event', - message: DebugProtocol.ProtocolMessage, - ): void { - message.type = (typ: any); + typ, + message) + { + message.type = typ; message.seq = this._sequence++; this._sendPreprocessors.forEach(processor => processor(message)); @@ -126,16 +126,16 @@ export default class V8Protocol { this._output('Content-Length: ' + length.toString() + TWO_CRLF + json); } - handleData(data: Buffer): void { + handleData(data) { this._rawData = Buffer.concat([this._rawData, data]); while (true) { if (this._contentLength >= 0) { if (this._rawData.length >= this._contentLength) { const message = this._rawData.toString( - 'utf8', - 0, - this._contentLength, - ); + 'utf8', + 0, + this._contentLength); + this._rawData = this._rawData.slice(this._contentLength); this._contentLength = -1; if (message.length > 0) { @@ -159,17 +159,17 @@ export default class V8Protocol { } } - _dispatch(body: string): void { + _dispatch(body) { try { const rawData = JSON.parse(body); this._receivePreprocessors.forEach(processor => processor(rawData)); switch (rawData.type) { case 'event': - this.onEvent((rawData: DebugProtocol.Event)); + this.onEvent(rawData); break; case 'response': - const response: DebugProtocol.Response = rawData; + const response = rawData; const clb = this._pendingRequests.get(response.request_seq); if (clb) { this._pendingRequests.delete(response.request_seq); @@ -177,19 +177,18 @@ export default class V8Protocol { } break; case 'request': - const request: DebugProtocol.Request = rawData; - const resp: DebugProtocol.Response = { + const request = rawData; + const resp = { type: 'response', seq: 0, command: request.command, request_seq: request.seq, - success: true, - }; + success: true }; + this.dispatchRequest(request, resp); - break; - } + break;} + } catch (e) { this.onServerError(new Error(e.message || e)); } - } -} + }}exports.default = V8Protocol; \ No newline at end of file diff --git a/modules/nuclide-debugger-common/VSCodeDebuggerAdapterService.js b/modules/nuclide-debugger-common/VSCodeDebuggerAdapterService.js index 333e5c53..07c47aa4 100644 --- a/modules/nuclide-debugger-common/VSCodeDebuggerAdapterService.js +++ b/modules/nuclide-debugger-common/VSCodeDebuggerAdapterService.js @@ -1,45 +1,55 @@ -/** - * 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 - * @format - */ - -import type {ConnectableObservable} from 'rxjs'; -import type {VSAdapterExecutableInfo, VsAdapterType} from './types'; -import type {ProcessInfo, ProcessMessage} from 'nuclide-commons/process'; - -import {psTree} from 'nuclide-commons/process'; -import VsAdapterSpawner from './VsAdapterSpawner'; -import {getAdapterExecutable} from './debugger-registry'; - -export class VsRawAdapterSpawnerService extends VsAdapterSpawner { - spawnAdapter( - adapter: VSAdapterExecutableInfo, - ): ConnectableObservable { - return super.spawnAdapter(adapter); - } - - write(input: string): Promise { - return super.write(input); - } - - dispose(): Promise { - return super.dispose(); - } -} - -export async function getProcessTree(): Promise> { - return psTree(); -} - -export async function getAdapterExecutableInfo( - adapterType: VsAdapterType, -): Promise { - return getAdapterExecutable(adapterType); -} +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.getAdapterExecutableInfo = exports.getProcessTree = exports.VsRawAdapterSpawnerService = undefined;var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));let getProcessTree = exports.getProcessTree = (() => {var _ref = (0, _asyncToGenerator.default)( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + function* () { + return (0, (_process || _load_process()).psTree)(); + });return function getProcessTree() {return _ref.apply(this, arguments);};})();let getAdapterExecutableInfo = exports.getAdapterExecutableInfo = (() => {var _ref2 = (0, _asyncToGenerator.default)( + + function* ( + adapterType) + { + return (0, (_debuggerRegistry || _load_debuggerRegistry()).getAdapterExecutable)(adapterType); + });return function getAdapterExecutableInfo(_x) {return _ref2.apply(this, arguments);};})();var _process;function _load_process() {return _process = require('nuclide-commons/process');}var _VsAdapterSpawner;function _load_VsAdapterSpawner() {return _VsAdapterSpawner = _interopRequireDefault(require('./VsAdapterSpawner'));}var _debuggerRegistry;function _load_debuggerRegistry() {return _debuggerRegistry = require('./debugger-registry');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */class VsRawAdapterSpawnerService extends (_VsAdapterSpawner || _load_VsAdapterSpawner()).default {spawnAdapter(adapter) {return super.spawnAdapter(adapter);}write(input) {return super.write(input);}dispose() {return super.dispose();}}exports.VsRawAdapterSpawnerService = VsRawAdapterSpawnerService; \ No newline at end of file diff --git a/modules/nuclide-debugger-common/VsAdapterSpawner.js b/modules/nuclide-debugger-common/VsAdapterSpawner.js index 60993de5..b8536445 100644 --- a/modules/nuclide-debugger-common/VsAdapterSpawner.js +++ b/modules/nuclide-debugger-common/VsAdapterSpawner.js @@ -1,61 +1,70 @@ -/** - * 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 - * @format - */ - -import type {ConnectableObservable} from 'rxjs'; -import type {ProcessMessage} from 'nuclide-commons/process'; -import type {VSAdapterExecutableInfo, IVsAdapterSpawner} from './types'; - -import { - observeProcessRaw, - getOriginalEnvironment, -} from 'nuclide-commons/process'; -import {Observable, Subject} from 'rxjs'; - -export default class VsAdapterSpawner implements IVsAdapterSpawner { - _stdin: Subject; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _process; + + + + + + + + + + + + + + + +function _load_process() {return _process = require('nuclide-commons/process');} + + + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +class VsAdapterSpawner { + constructor() { - this._stdin = new Subject(); + this._stdin = new _rxjsBundlesRxMinJs.Subject(); } spawnAdapter( - adapter: VSAdapterExecutableInfo, - ): ConnectableObservable { - const environment = Observable.fromPromise(getOriginalEnvironment()); - return Observable.forkJoin(this._stdin.buffer(environment), environment) - .switchMap(([stdinBuffer, env]) => { - const options = { - stdio: [ - 'pipe', // stdin - 'pipe', // stdout - 'pipe', // stderr - ], - env: {...env, ELECTRON_RUN_AS_NODE: 1}, - input: Observable.from(stdinBuffer).concat(this._stdin), - killTreeWhenDone: true, - }; - if (adapter.command === 'node') { - adapter.command = process.execPath; - } - return observeProcessRaw(adapter.command, adapter.args, options); - }) - .publish(); - } + adapter) + { + const environment = _rxjsBundlesRxMinJs.Observable.fromPromise((0, (_process || _load_process()).getOriginalEnvironment)()); + return _rxjsBundlesRxMinJs.Observable.forkJoin(this._stdin.buffer(environment), environment). + switchMap(([stdinBuffer, env]) => { + const options = { + stdio: [ + 'pipe', // stdin + 'pipe', // stdout + 'pipe'], - async write(input: string): Promise { - this._stdin.next(input); + env: Object.assign({}, env, { ELECTRON_RUN_AS_NODE: 1 }), + input: _rxjsBundlesRxMinJs.Observable.from(stdinBuffer).concat(this._stdin), + killTreeWhenDone: true }; + + if (adapter.command === 'node') { + adapter.command = process.execPath; + } + return (0, (_process || _load_process()).observeProcessRaw)(adapter.command, adapter.args, options); + }). + publish(); } - async dispose(): Promise { - this._stdin.complete(); + write(input) {var _this = this;return (0, _asyncToGenerator.default)(function* () { + _this._stdin.next(input);})(); } -} + + dispose() {var _this2 = this;return (0, _asyncToGenerator.default)(function* () { + _this2._stdin.complete();})(); + }}exports.default = VsAdapterSpawner; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-debugger-common/VsDebugSession.js b/modules/nuclide-debugger-common/VsDebugSession.js index 4b698454..8b19a3db 100644 --- a/modules/nuclide-debugger-common/VsDebugSession.js +++ b/modules/nuclide-debugger-common/VsDebugSession.js @@ -1,173 +1,173 @@ -/** - * 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 - * @format - */ - -import * as DebugProtocol from 'vscode-debugprotocol'; -import type { - IVsAdapterSpawner, - MessageProcessor, - VSAdapterExecutableInfo, -} from './types'; -import type {ProcessMessage} from 'nuclide-commons/process'; - -import VsAdapterSpawner from './VsAdapterSpawner'; -import V8Protocol from './V8Protocol'; -import {Observable, Subject} from 'rxjs'; -import idx from 'idx'; -import invariant from 'assert'; -import {trackTiming} from 'nuclide-commons/analytics'; - -export interface AdapterExitedEvent extends DebugProtocol.DebugEvent { - event: 'adapter-exited'; - body: {exitCode: number}; -} +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _vscodeDebugprotocol; + + + + + + + + + + + +function _load_vscodeDebugprotocol() {return _vscodeDebugprotocol = _interopRequireWildcard(require('vscode-debugprotocol'));}var _VsAdapterSpawner; + + + + + + + +function _load_VsAdapterSpawner() {return _VsAdapterSpawner = _interopRequireDefault(require('./VsAdapterSpawner'));}var _V8Protocol; +function _load_V8Protocol() {return _V8Protocol = _interopRequireDefault(require('./V8Protocol'));} +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');var _idx; +function _load_idx() {return _idx = _interopRequireDefault(require('idx'));}var _analytics; -export type AdapterAnalyticsExtras = { - adapter: string, - host: string, - isRemote: boolean, -}; +function _load_analytics() {return _analytics = require('nuclide-commons/analytics');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */ -function raiseAdapterExitedEvent(exitCode: number): AdapterExitedEvent { + +function raiseAdapterExitedEvent(exitCode) { return { seq: 0, type: 'event', event: 'adapter-exited', - body: {exitCode}, - }; + body: { exitCode } }; + } -type RunInTerminalHandler = ( - arguments: DebugProtocol.RunInTerminalRequestArguments, -) => Promise; + + + /** - * Use V8 JSON-RPC protocol to send & receive messages - * (requests, responses & events) over `stdio` of adapter child processes. - */ -export default class VsDebugSession extends V8Protocol { - _readyForBreakpoints: boolean; - _disconnected: boolean; - - _adapterProcessSubscription: ?rxjs$Subscription; - _startTime: number; - - capabilities: DebugProtocol.Capabilities; - _adapterExecutable: VSAdapterExecutableInfo; - _logger: log4js$Logger; - _spawner: IVsAdapterSpawner; - _adapterAnalyticsExtras: AdapterAnalyticsExtras; - - _onDidInitialize: Subject; - _onDidStop: Subject; - _onDidContinued: Subject; - _onDidTerminateDebugee: Subject; - _onDidExitDebugee: Subject; - _onDidExitAdapter: Subject; - _onDidThread: Subject; - _onDidOutput: Subject; - _onDidBreakpoint: Subject; - _onDidModule: Subject; - _onDidLoadSource: Subject; - _onDidCustom: Subject; - _onDidEvent: Subject; - _runInTerminalHandler: ?RunInTerminalHandler; + * Use V8 JSON-RPC protocol to send & receive messages + * (requests, responses & events) over `stdio` of adapter child processes. + */ +class VsDebugSession extends (_V8Protocol || _load_V8Protocol()).default { + + + + + + + + + + + + + + + + + + + + + + + + + + constructor( - id: string, - logger: log4js$Logger, - adapterExecutable: VSAdapterExecutableInfo, - adapterAnalyticsExtras: ?AdapterAnalyticsExtras, - spawner?: IVsAdapterSpawner, - sendPreprocessors?: MessageProcessor[] = [], - receivePreprocessors?: MessageProcessor[] = [], - runInTerminalHandler?: RunInTerminalHandler, - ) { + id, + logger, + adapterExecutable, + adapterAnalyticsExtras, + spawner, + sendPreprocessors = [], + receivePreprocessors = [], + runInTerminalHandler) + { super(id, logger, sendPreprocessors, receivePreprocessors); this._adapterExecutable = adapterExecutable; this._logger = logger; this._readyForBreakpoints = false; - this._spawner = spawner == null ? new VsAdapterSpawner() : spawner; - this._adapterAnalyticsExtras = {...adapterAnalyticsExtras}; - - this._onDidInitialize = new Subject(); - this._onDidStop = new Subject(); - this._onDidContinued = new Subject(); - this._onDidTerminateDebugee = new Subject(); - this._onDidExitDebugee = new Subject(); - this._onDidExitAdapter = new Subject(); - this._onDidThread = new Subject(); - this._onDidOutput = new Subject(); - this._onDidBreakpoint = new Subject(); - this._onDidModule = new Subject(); - this._onDidLoadSource = new Subject(); - this._onDidCustom = new Subject(); - this._onDidEvent = new Subject(); + this._spawner = spawner == null ? new (_VsAdapterSpawner || _load_VsAdapterSpawner()).default() : spawner; + this._adapterAnalyticsExtras = Object.assign({}, adapterAnalyticsExtras); + + this._onDidInitialize = new _rxjsBundlesRxMinJs.Subject(); + this._onDidStop = new _rxjsBundlesRxMinJs.Subject(); + this._onDidContinued = new _rxjsBundlesRxMinJs.Subject(); + this._onDidTerminateDebugee = new _rxjsBundlesRxMinJs.Subject(); + this._onDidExitDebugee = new _rxjsBundlesRxMinJs.Subject(); + this._onDidExitAdapter = new _rxjsBundlesRxMinJs.Subject(); + this._onDidThread = new _rxjsBundlesRxMinJs.Subject(); + this._onDidOutput = new _rxjsBundlesRxMinJs.Subject(); + this._onDidBreakpoint = new _rxjsBundlesRxMinJs.Subject(); + this._onDidModule = new _rxjsBundlesRxMinJs.Subject(); + this._onDidLoadSource = new _rxjsBundlesRxMinJs.Subject(); + this._onDidCustom = new _rxjsBundlesRxMinJs.Subject(); + this._onDidEvent = new _rxjsBundlesRxMinJs.Subject(); this.capabilities = {}; this._runInTerminalHandler = runInTerminalHandler || null; } - observeInitializeEvents(): Observable { + observeInitializeEvents() { return this._onDidInitialize.asObservable(); } - observeStopEvents(): Observable { + observeStopEvents() { return this._onDidStop.asObservable(); } - observeContinuedEvents(): Observable { + observeContinuedEvents() { return this._onDidContinued.asObservable(); } - observeTerminateDebugeeEvents(): Observable { + observeTerminateDebugeeEvents() { return this._onDidTerminateDebugee.asObservable(); } - observeExitedDebugeeEvents(): Observable { + observeExitedDebugeeEvents() { return this._onDidExitDebugee.asObservable(); } - observeAdapterExitedEvents(): Observable { + observeAdapterExitedEvents() { return this._onDidExitAdapter.asObservable(); } - observeThreadEvents(): Observable { + observeThreadEvents() { return this._onDidThread.asObservable(); } - observeOutputEvents(): Observable { + observeOutputEvents() { return this._onDidOutput.asObservable(); } - observeBreakpointEvents(): Observable { + observeBreakpointEvents() { return this._onDidBreakpoint.asObservable(); } - observeModuleEvents(): Observable { + observeModuleEvents() { return this._onDidModule.asObservable(); } - observeSourceLoadedEvents(): Observable { + observeSourceLoadedEvents() { return this._onDidLoadSource.asObservable(); } - observeCustomEvents(): Observable { + observeCustomEvents() { return this._onDidCustom.asObservable(); } - observeAllEvents(): Observable { + observeAllEvents() { return this._onDidEvent.asObservable(); } - _initServer(): void { + _initServer() { if (this._adapterProcessSubscription != null) { return; } @@ -176,54 +176,54 @@ export default class VsDebugSession extends V8Protocol { this._startTime = new Date().getTime(); } - custom(request: string, args: any): Promise { + custom(request, args) { return this.send(request, args); } - send(command: string, args: any): Promise { + send(command, args) { this._logger.info('Send request:', command, args); this._initServer(); - const operation = (): Promise => { + const operation = () => { // Babel Bug: `super` isn't working with `async` return super.send(command, args).then( - response => { - this._logger.info('Received response:', response); - return response; - }, - (errorResponse: DebugProtocol.ErrorResponse) => { - let formattedError = - idx(errorResponse, _ => _.body.error.format) || - idx(errorResponse, _ => _.message); - if (formattedError === '{_stack}') { - formattedError = JSON.stringify(errorResponse.body.error); - } else if (formattedError == null) { - formattedError = [ - `command: ${command}`, - `args: ${JSON.stringify(args)}`, - `response: ${JSON.stringify(errorResponse)}`, - `adapterExecutable: , ${JSON.stringify(this._adapterExecutable)}`, - ].join(', '); - } - throw new Error(formattedError); - }, - ); + response => { + this._logger.info('Received response:', response); + return response; + }, + errorResponse => {var _ref, _ref2, _ref3, _ref4; + let formattedError = + ((_ref = errorResponse) != null ? (_ref2 = _ref.body) != null ? (_ref3 = _ref2.error) != null ? _ref3.format : _ref3 : _ref2 : _ref) || ((_ref4 = + errorResponse) != null ? _ref4.message : _ref4); + if (formattedError === '{_stack}') { + formattedError = JSON.stringify(errorResponse.body.error); + } else if (formattedError == null) { + formattedError = [ + `command: ${command}`, + `args: ${JSON.stringify(args)}`, + `response: ${JSON.stringify(errorResponse)}`, + `adapterExecutable: , ${JSON.stringify(this._adapterExecutable)}`]. + join(', '); + } + throw new Error(formattedError); + }); + }; - return trackTiming( - `vs-debug-session:${command}`, - operation, - this._adapterAnalyticsExtras, - ); + return (0, (_analytics || _load_analytics()).trackTiming)( + `vs-debug-session:${command}`, + operation, + this._adapterAnalyticsExtras); + } - onEvent(event: DebugProtocol.Event | AdapterExitedEvent): void { + onEvent(event) { if (event.body != null) { // $FlowFixMe `sessionId` isn't in the type def. event.body.sessionId = this.getId(); } else { // $FlowFixMe `event.body` type def. - event.body = {sessionId: this.getId()}; + event.body = { sessionId: this.getId() }; } this._onDidEvent.next(event); @@ -266,282 +266,282 @@ export default class VsDebugSession extends V8Protocol { default: this._onDidCustom.next(event); this._logger.info('Custom event type:', event); - break; - } + break;} + } - getCapabilities(): DebugProtocol.Capabilities { + getCapabilities() { return this.capabilities; } - async initialize( - args: DebugProtocol.InitializeRequestArguments, - ): Promise { - const response = await this.send('initialize', args); - return this._readCapabilities(response); + initialize( + args) + {var _this = this;return (0, _asyncToGenerator.default)(function* () { + const response = yield _this.send('initialize', args); + return _this._readCapabilities(response);})(); } - _readCapabilities(response: any): any { + _readCapabilities(response) { if (response) { - this.capabilities = { - ...this.capabilities, - ...response.body, - }; + this.capabilities = Object.assign({}, + this.capabilities, + response.body); + } return response; } - async launch( - args: DebugProtocol.LaunchRequestArguments, - ): Promise { - const response = await this.send('launch', args); - return this._readCapabilities(response); + launch( + args) + {var _this2 = this;return (0, _asyncToGenerator.default)(function* () { + const response = yield _this2.send('launch', args); + return _this2._readCapabilities(response);})(); } - async attach( - args: DebugProtocol.AttachRequestArguments, - ): Promise { - const response = await this.send('attach', args); - return this._readCapabilities(response); + attach( + args) + {var _this3 = this;return (0, _asyncToGenerator.default)(function* () { + const response = yield _this3.send('attach', args); + return _this3._readCapabilities(response);})(); } - next(args: DebugProtocol.NextArguments): Promise { + next(args) { this._fireFakeContinued(args.threadId); return this.send('next', args); } stepIn( - args: DebugProtocol.StepInArguments, - ): Promise { + args) + { this._fireFakeContinued(args.threadId); return this.send('stepIn', args); } stepOut( - args: DebugProtocol.StepOutArguments, - ): Promise { + args) + { this._fireFakeContinued(args.threadId); return this.send('stepOut', args); } continue( - args: DebugProtocol.ContinueArguments, - ): Promise { + args) + { this._fireFakeContinued(args.threadId); return this.send('continue', args); } pause( - args: DebugProtocol.PauseArguments, - ): Promise { + args) + { return this.send('pause', args); } setVariable( - args: DebugProtocol.SetVariableArguments, - ): Promise { + args) + { return this.send('setVariable', args); } restartFrame( - args: DebugProtocol.RestartFrameArguments, - threadId: number, - ): Promise { + args, + threadId) + { this._fireFakeContinued(threadId); return this.send('restartFrame', args); } completions( - args: DebugProtocol.CompletionsArguments, - ): Promise { + args) + { return this.send('completions', args); } - async disconnect( - restart?: boolean = false, - force?: boolean = false, - ): Promise { - if (this._disconnected && force) { - this._stopServer(); - return; - } + disconnect( + restart = false, + force = false) + {var _this4 = this;return (0, _asyncToGenerator.default)(function* () { + if (_this4._disconnected && force) { + _this4._stopServer(); + return; + } - if (this._adapterProcessSubscription != null && !this._disconnected) { - // point of no return: from now on don't report any errors - this._disconnected = true; - await this.send('disconnect', {restart}); - this._stopServer(); - } + if (_this4._adapterProcessSubscription != null && !_this4._disconnected) { + // point of no return: from now on don't report any errors + _this4._disconnected = true; + yield _this4.send('disconnect', { restart }); + _this4._stopServer(); + }})(); } setBreakpoints( - args: DebugProtocol.SetBreakpointsArguments, - ): Promise { + args) + { return this.send('setBreakpoints', args); } setFunctionBreakpoints( - args: DebugProtocol.SetFunctionBreakpointsArguments, - ): Promise { + args) + { return this.send('setFunctionBreakpoints', args); } setExceptionBreakpoints( - args: DebugProtocol.SetExceptionBreakpointsArguments, - ): Promise { + args) + { return this.send('setExceptionBreakpoints', args); } - configurationDone(): Promise { + configurationDone() { return this.send('configurationDone', null); } stackTrace( - args: DebugProtocol.StackTraceArguments, - ): Promise { + args) + { return this.send('stackTrace', args); } exceptionInfo( - args: DebugProtocol.ExceptionInfoArguments, - ): Promise { + args) + { return this.send('exceptionInfo', args); } scopes( - args: DebugProtocol.ScopesArguments, - ): Promise { + args) + { return this.send('scopes', args); } variables( - args: DebugProtocol.VariablesArguments, - ): Promise { + args) + { return this.send('variables', args); } source( - args: DebugProtocol.SourceArguments, - ): Promise { + args) + { return this.send('source', args); } - threads(): Promise { + threads() { return this.send('threads', null); } evaluate( - args: DebugProtocol.EvaluateArguments, - ): Promise { + args) + { return this.send('evaluate', args); } stepBack( - args: DebugProtocol.StepBackArguments, - ): Promise { + args) + { this._fireFakeContinued(args.threadId); return this.send('stepBack', args); } reverseContinue( - args: DebugProtocol.ReverseContinueArguments, - ): Promise { + args) + { this._fireFakeContinued(args.threadId); return this.send('reverseContinue', args); } nuclide_continueToLocation( - args: DebugProtocol.nuclide_ContinueToLocationArguments, - ): Promise { + args) + { return this.custom('nuclide_continueToLocation', args); } - getLengthInSeconds(): number { + getLengthInSeconds() { return (new Date().getTime() - this._startTime) / 1000; } - async dispatchRequest( - request: DebugProtocol.Request, - response: DebugProtocol.Response, - ): Promise { - if (request.command === 'runInTerminal') { - const runInTerminalHandler = this._runInTerminalHandler; - if (runInTerminalHandler == null) { - this._logger.error( + dispatchRequest( + request, + response) + {var _this5 = this;return (0, _asyncToGenerator.default)(function* () { + if (request.command === 'runInTerminal') { + const runInTerminalHandler = _this5._runInTerminalHandler; + if (runInTerminalHandler == null) { + _this5._logger.error( "'runInTerminal' isn't supported for this debug session", - request, - ); - return; - } - try { - await runInTerminalHandler((request.arguments: any)); - } catch (error) { + request); + + return; + } + try { + yield runInTerminalHandler(request.arguments); + } catch (error) { + response.success = false; + response.message = error.message; + } + _this5.sendResponse(response); + } else if (request.command === 'handshake') { + _this5._logger.error('TODO: handshake', request); + } else { response.success = false; - response.message = error.message; - } - this.sendResponse(response); - } else if (request.command === 'handshake') { - this._logger.error('TODO: handshake', request); - } else { - response.success = false; - response.message = `unknown request '${request.command}'`; - this.sendResponse(response); - } + response.message = `unknown request '${request.command}'`; + _this5.sendResponse(response); + }})(); } _fireFakeContinued( - threadId: number, - allThreadsContinued?: boolean = false, - ): void { - const event: DebugProtocol.ContinuedEvent = { + threadId, + allThreadsContinued = false) + { + const event = { type: 'event', event: 'continued', body: { threadId, // $FlowFixMe - allThreadsContinued, - }, - seq: 0, - }; + allThreadsContinued }, + + seq: 0 }; + this._onDidContinued.next(event); this._onDidEvent.next(event); } - _startServer(): void { - this._adapterProcessSubscription = this._spawner - .spawnAdapter(this._adapterExecutable) - .refCount() - .subscribe( - (message: ProcessMessage) => { - if (message.kind === 'stdout') { - this.handleData(new Buffer(message.data)); - } else if (message.kind === 'stderr') { - const event: DebugProtocol.OutputEvent = ({ - type: 'event', - event: 'output', - body: { - category: 'stderr', - output: message.data, - }, - seq: 0, - }: any); - this._onDidOutput.next(event); - this._onDidEvent.next(event); - this._logger.error(`adapter stderr: ${message.data}`); - } else { - invariant(message.kind === 'exit'); - this.onServerExit(message.exitCode || 0); - } - }, - (err: Error) => { - this.onServerError(err); - }, - ); + _startServer() { + this._adapterProcessSubscription = this._spawner. + spawnAdapter(this._adapterExecutable). + refCount(). + subscribe( + message => { + if (message.kind === 'stdout') { + this.handleData(new Buffer(message.data)); + } else if (message.kind === 'stderr') { + const event = { + type: 'event', + event: 'output', + body: { + category: 'stderr', + output: message.data }, + + seq: 0 }; + + this._onDidOutput.next(event); + this._onDidEvent.next(event); + this._logger.error(`adapter stderr: ${message.data}`); + } else {if (!( + message.kind === 'exit')) {throw new Error('Invariant violation: "message.kind === \'exit\'"');} + this.onServerExit(message.exitCode || 0); + } + }, + err => { + this.onServerError(err); + }); + this.setOutput(this._spawner.write.bind(this._spawner)); } - _stopServer(): void { + _stopServer() { this.onEvent(raiseAdapterExitedEvent(0)); if (this._adapterProcessSubscription == null) { return; @@ -552,7 +552,7 @@ export default class VsDebugSession extends V8Protocol { this._endHandlers(); } - _endHandlers(): void { + _endHandlers() { this._onDidInitialize.complete(); this._onDidStop.complete(); this._onDidContinued.complete(); @@ -568,33 +568,32 @@ export default class VsDebugSession extends V8Protocol { this._onDidEvent.complete(); } - onServerError(error: Error): void { + onServerError(error) { this._logger.error('Adapter error:', error); this._stopServer(); } - onServerExit(code: number): void { + onServerExit(code) { if (this._adapterProcessSubscription != null) { this._adapterProcessSubscription.unsubscribe(); this._adapterProcessSubscription = null; } if (!this._disconnected) { this._logger.error( - `Debug adapter process has terminated unexpectedly ${code}`, - ); + `Debug adapter process has terminated unexpectedly ${code}`); + } this.onEvent(raiseAdapterExitedEvent(code)); } - isReadyForBreakpoints(): boolean { + isReadyForBreakpoints() { return this._readyForBreakpoints; } - isDisconnected(): boolean { + isDisconnected() { return this._disconnected; } - dispose(): void { + dispose() { this.disconnect(); - } -} + }}exports.default = VsDebugSession; \ No newline at end of file diff --git a/modules/nuclide-debugger-common/VspProcessInfo.js b/modules/nuclide-debugger-common/VspProcessInfo.js index 2f2b6cc2..4acecb94 100644 --- a/modules/nuclide-debugger-common/VspProcessInfo.js +++ b/modules/nuclide-debugger-common/VspProcessInfo.js @@ -1,68 +1,68 @@ -/** - * 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 - * @format - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type { - ControlButtonSpecification, - DebuggerCapabilities, - DebuggerConfigAction, - DebuggerProperties, - IProcessConfig, - IVspInstance, - MessageProcessor, - VsAdapterType, - VSAdapterExecutableInfo, -} from 'nuclide-debugger-common'; -import * as DebugProtocol from 'vscode-debugprotocol'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import {Observable} from 'rxjs'; - -type MessagePreprocessors = { - vspAdapterPreprocessor: MessageProcessor, - vspClientPreprocessor: MessageProcessor, -}; - -type CustomDebuggerCapabilities = { - threads?: boolean, -}; - -type CustomDebuggerProperties = { - customControlButtons?: Array, - threadsComponentTitle?: string, -}; - -export default class VspProcessInfo { - _targetUri: NuclideUri; - _debugMode: DebuggerConfigAction; - _adapterType: VsAdapterType; - _adapterExecutable: ?VSAdapterExecutableInfo; - _config: Object; - _customCapabilities: CustomDebuggerCapabilities; - _customProperties: CustomDebuggerProperties; - _preprocessors: ?MessagePreprocessors; - _vspInstance: ?IVspInstance; - _disposables: UniversalDisposable; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _vscodeDebugprotocol; + + + + + + + + + + + + + + + + + + + + + + + +function _load_vscodeDebugprotocol() {return _vscodeDebugprotocol = _interopRequireWildcard(require('vscode-debugprotocol'));}var _UniversalDisposable; + +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));} +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js');function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + + + + + + + + + + + + + + + +class VspProcessInfo { + + + + + + + + + + constructor( - targetUri: NuclideUri, - debugMode: DebuggerConfigAction, - adapterType: VsAdapterType, - adapterExecutable: ?VSAdapterExecutableInfo, - config: Object, - customCapabilities?: ?CustomDebuggerCapabilities, - customProperties?: ?CustomDebuggerProperties, - preprocessors?: ?MessagePreprocessors, - ) { + targetUri, + debugMode, + adapterType, + adapterExecutable, + config, + customCapabilities, + customProperties, + preprocessors) + { this._targetUri = targetUri; this._debugMode = debugMode; this._adapterType = adapterType; @@ -71,63 +71,63 @@ export default class VspProcessInfo { this._customCapabilities = customCapabilities || {}; this._customProperties = customProperties || {}; this._preprocessors = preprocessors; - this._disposables = new UniversalDisposable(); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(); } - getTargetUri(): NuclideUri { + getTargetUri() { return this._targetUri; } - setVspDebuggerInstance(vspInstance: IVspInstance): void { + setVspDebuggerInstance(vspInstance) { this._vspInstance = vspInstance; } - _getDebuggerCapabilities(): DebuggerCapabilities { - return { - threads: false, - ...this._customCapabilities, - }; + _getDebuggerCapabilities() { + return Object.assign({ + threads: false }, + this._customCapabilities); + } - _getDebuggerProps(): DebuggerProperties { - return { + _getDebuggerProps() { + return Object.assign({ customControlButtons: [], - threadsComponentTitle: 'Threads', - ...this._customProperties, - }; + threadsComponentTitle: 'Threads' }, + this._customProperties); + } - async customRequest( - request: string, - args: any, - ): Promise { - if (this._vspInstance != null) { - return this._vspInstance.customRequest(request, args); - } else { - throw new Error('Cannot send custom requests to inactive debug sessions'); - } + customRequest( + request, + args) + {var _this = this;return (0, _asyncToGenerator.default)(function* () { + if (_this._vspInstance != null) { + return _this._vspInstance.customRequest(request, args); + } else { + throw new Error('Cannot send custom requests to inactive debug sessions'); + }})(); } - observeCustomEvents(): Observable { + observeCustomEvents() { if (this._vspInstance != null) { return this._vspInstance.observeCustomEvents(); } else { - return Observable.throw( - new Error('Cannot send custom requests to inactive debug sessions'), - ); + return _rxjsBundlesRxMinJs.Observable.throw( + new Error('Cannot send custom requests to inactive debug sessions')); + } } - addCustomDisposable(disposable: IDisposable): void { + addCustomDisposable(disposable) { this._disposables.add(disposable); } - dispose(): void { + dispose() { this._disposables.dispose(); this._vspInstance = null; } - getProcessConfig(): IProcessConfig { + getProcessConfig() { return { targetUri: this._targetUri, debugMode: this._debugMode, @@ -137,17 +137,26 @@ export default class VspProcessInfo { properties: this._getDebuggerProps(), config: this._config, clientPreprocessor: - this._preprocessors == null - ? null - : this._preprocessors.vspClientPreprocessor, + this._preprocessors == null ? + null : + this._preprocessors.vspClientPreprocessor, adapterPreprocessor: - this._preprocessors == null - ? null - : this._preprocessors.vspAdapterPreprocessor, - }; + this._preprocessors == null ? + null : + this._preprocessors.vspAdapterPreprocessor }; + } - getConfig(): Object { + getConfig() { return this._config; - } -} + }}exports.default = VspProcessInfo; /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-debugger-common/autogen-utils.js b/modules/nuclide-debugger-common/autogen-utils.js index 7dc9ba59..af695281 100644 --- a/modules/nuclide-debugger-common/autogen-utils.js +++ b/modules/nuclide-debugger-common/autogen-utils.js @@ -1,86 +1,86 @@ -/** - * 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 - * @format - */ - -import type {AutoGenProperty} from './types'; -import type { - NativeVsAdapterType, - AutoGenLaunchConfig, - AutoGenAttachConfig, - AutoGenConfig, -} from './types'; -import * as React from 'react'; - -import {VsAdapterTypes} from './constants'; - -export function generatePropertyArray( - launchOrAttachConfigProperties: Object, - required: string[], - visible: string[], -): AutoGenProperty[] { - const propertyArray = Object.entries(launchOrAttachConfigProperties) - .map(property => { - const name = property[0]; - const propertyDetails: any = property[1]; - const autoGenProperty: AutoGenProperty = { - name, - type: propertyDetails.type, - description: propertyDetails.description, - required: required.includes(name), - visible: visible.includes(name), - }; - if (typeof propertyDetails.default !== 'undefined') { - autoGenProperty.defaultValue = propertyDetails.default; - } - if ( - propertyDetails.items != null && - typeof propertyDetails.items.type !== 'undefined' - ) { - autoGenProperty.itemType = propertyDetails.items.type; - } - if (typeof propertyDetails.enums !== 'undefined') { - autoGenProperty.enums = propertyDetails.enums; - } - return autoGenProperty; - }) - .sort((p1, p2) => { - // TODO (goom): sort all configs, not just ones generated from the json - if (p1.required && !p2.required) { - return -1; - } - if (p2.required && !p1.required) { - return 1; - } - return 0; - }); - return propertyArray; -} - -export function getNativeAutoGenConfig( - vsAdapterType: NativeVsAdapterType, -): AutoGenConfig { - const program = { - name: 'program', - type: 'string', - description: 'Input the program/executable you want to launch', - required: true, - visible: true, - }; - const cwd = { - name: 'cwd', +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + + + + + + + + + + +generatePropertyArray = generatePropertyArray;exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +getNativeAutoGenConfig = getNativeAutoGenConfig;var _react = _interopRequireWildcard(require('react'));var _constants;function _load_constants() {return _constants = require('./constants');}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} /** + * 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. + * + * + * @format + */function generatePropertyArray(launchOrAttachConfigProperties, required, visible) {const propertyArray = Object.entries(launchOrAttachConfigProperties).map(property => {const name = property[0];const propertyDetails = property[1];const autoGenProperty = { name, type: propertyDetails.type, description: propertyDetails.description, required: required.includes(name), visible: visible.includes(name) };if (typeof propertyDetails.default !== 'undefined') {autoGenProperty.defaultValue = propertyDetails.default;}if (propertyDetails.items != null && typeof propertyDetails.items.type !== 'undefined') {autoGenProperty.itemType = propertyDetails.items.type;}if (typeof propertyDetails.enums !== 'undefined') {autoGenProperty.enums = propertyDetails.enums;}return autoGenProperty;}).sort((p1, p2) => {// TODO (goom): sort all configs, not just ones generated from the json + if (p1.required && !p2.required) {return -1;}if (p2.required && !p1.required) {return 1;}return 0;});return propertyArray;}function getNativeAutoGenConfig(vsAdapterType) {const program = { name: 'program', type: 'string', description: 'Input the program/executable you want to launch', required: true, visible: true };const cwd = { name: 'cwd', type: 'string', description: 'Working directory for the launched executable', required: true, - visible: true, - }; + visible: true }; + const args = { name: 'args', type: 'array', @@ -88,8 +88,8 @@ export function getNativeAutoGenConfig( description: 'Arguments to the executable', required: false, defaultValue: '', - visible: true, - }; + visible: true }; + const env = { name: 'env', type: 'array', @@ -97,22 +97,22 @@ export function getNativeAutoGenConfig( description: 'Environment variables (e.g., SHELL=/bin/bash PATH=/bin)', required: false, defaultValue: '', - visible: true, - }; + visible: true }; + const sourcePath = { name: 'sourcePath', type: 'string', description: 'Optional base path for sources', required: false, defaultValue: '', - visible: true, - }; + visible: true }; + const debugTypeMessage = `using ${ - vsAdapterType === VsAdapterTypes.NATIVE_GDB ? 'gdb' : 'lldb' + vsAdapterType === (_constants || _load_constants()).VsAdapterTypes.NATIVE_GDB ? 'gdb' : 'lldb' }`; - const autoGenLaunchConfig: AutoGenLaunchConfig = { + const autoGenLaunchConfig = { launch: true, vsAdapterType, threads: true, @@ -120,25 +120,25 @@ export function getNativeAutoGenConfig( scriptPropertyName: 'program', scriptExtension: '.c', cwdPropertyName: 'working directory', - header:

    Debug native programs {debugTypeMessage}.

    , - }; + header: _react.createElement('p', null, 'Debug native programs ', debugTypeMessage, '.') }; + const pid = { name: 'pid', type: 'process', description: '', required: true, - visible: true, - }; - const autoGenAttachConfig: AutoGenAttachConfig = { + visible: true }; + + const autoGenAttachConfig = { launch: false, vsAdapterType, threads: true, properties: [pid, sourcePath], - header:

    Attach to a running native process {debugTypeMessage}

    , - }; + header: _react.createElement('p', null, 'Attach to a running native process ', debugTypeMessage) }; + return { launch: autoGenLaunchConfig, - attach: autoGenAttachConfig, - }; -} + attach: autoGenAttachConfig }; + +} \ No newline at end of file diff --git a/modules/nuclide-debugger-common/constants.js b/modules/nuclide-debugger-common/constants.js index 4e1d9763..de3feeb5 100644 --- a/modules/nuclide-debugger-common/constants.js +++ b/modules/nuclide-debugger-common/constants.js @@ -1,18 +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 - * @format - */ +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); + + + + + + -import type {VsAdapterType} from './types'; -export const VsAdapterTypes = Object.freeze({ + + + + + +const VsAdapterTypes = exports.VsAdapterTypes = Object.freeze({ HHVM: 'hhvm', PYTHON: 'python', REACT_NATIVE: 'react-native', @@ -22,8 +22,18 @@ export const VsAdapterTypes = Object.freeze({ OCAML: 'ocaml', MOBILEJS: 'mobilejs', NATIVE_GDB: 'native_gdb', - NATIVE_LLDB: 'native_lldb', -}); + NATIVE_LLDB: 'native_lldb' }); + // This is to work around flow's missing support of enums. -(VsAdapterTypes: {[key: string]: VsAdapterType}); +/** + * 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. + * + * + * @format + */VsAdapterTypes; \ No newline at end of file diff --git a/modules/nuclide-debugger-common/debug-adapter-service.js b/modules/nuclide-debugger-common/debug-adapter-service.js index 0954ea33..feec0dcb 100644 --- a/modules/nuclide-debugger-common/debug-adapter-service.js +++ b/modules/nuclide-debugger-common/debug-adapter-service.js @@ -1,36 +1,46 @@ -/** - * 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 - * @format - */ - -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import typeof * as VSCodeDebuggerAdapterService from './VSCodeDebuggerAdapterService'; - -import * as VSCodeDebuggerAdapterServiceLocal from './VSCodeDebuggerAdapterService'; - -export function getVSCodeDebuggerAdapterServiceByNuclideUri( - uri: NuclideUri, -): VSCodeDebuggerAdapterService { - let rpcService: ?nuclide$RpcService = null; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + + + + +getVSCodeDebuggerAdapterServiceByNuclideUri = getVSCodeDebuggerAdapterServiceByNuclideUri;var _VSCodeDebuggerAdapterService;function _load_VSCodeDebuggerAdapterService() {return _VSCodeDebuggerAdapterService = _interopRequireWildcard(require('./VSCodeDebuggerAdapterService'));}function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}}function getVSCodeDebuggerAdapterServiceByNuclideUri( +uri) +{ + let rpcService = null; // Atom's service hub is synchronous. - atom.packages.serviceHub - .consume('nuclide-rpc-services', '0.0.0', provider => { - rpcService = provider; - }) - .dispose(); + atom.packages.serviceHub. + consume('nuclide-rpc-services', '0.0.0', provider => { + rpcService = provider; + }). + dispose(); if (rpcService != null) { return rpcService.getServiceByNuclideUri( - 'VSCodeDebuggerAdapterService', - uri, - ); + 'VSCodeDebuggerAdapterService', + uri); + } else { - return VSCodeDebuggerAdapterServiceLocal; + return _VSCodeDebuggerAdapterService || _load_VSCodeDebuggerAdapterService(); } -} +} /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-debugger-common/debugger-registry.js b/modules/nuclide-debugger-common/debugger-registry.js index 7344f641..3921f6ea 100644 --- a/modules/nuclide-debugger-common/debugger-registry.js +++ b/modules/nuclide-debugger-common/debugger-registry.js @@ -1,187 +1,191 @@ -/** - * 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 - * @format - */ - -import nuclideUri from 'nuclide-commons/nuclideUri'; -import fs from 'fs'; - -import type {VSAdapterExecutableInfo, VsAdapterType} from './types'; - -type AdapterInfo = { - executable: VSAdapterExecutableInfo, - root: string, -}; - -const modulesPath = nuclideUri.dirname(__dirname); - -function resolvePackagePath(packageName: string): string { - const bundledPath = nuclideUri.join(modulesPath, packageName); - if (fs.existsSync(bundledPath)) { - return bundledPath; - } else if (typeof atom !== 'undefined') { - const pkg = atom.packages.getActivePackage(packageName); - if (pkg != null) { - return nuclideUri.join(pkg.path, 'node_modules', packageName); - } - } - return 'DEBUGGER_RUNTIME_NOT_FOUND'; -} - -const _adapters: Map = new Map([ - [ - 'node', - { - executable: { - command: 'node', - args: [ - nuclideUri.join( - resolvePackagePath('atom-ide-debugger-node'), - 'VendorLib/vscode-node-debug2/out/src/nodeDebug.js', - ), - ], - }, - root: resolvePackagePath('atom-ide-debugger-node'), - }, - ], - [ - 'python', - { - executable: { - command: 'node', - args: [ - nuclideUri.join( - resolvePackagePath('atom-ide-debugger-python'), - 'VendorLib/vs-py-debugger/out/client/debugger/Main.js', - ), - ], - }, - root: resolvePackagePath('atom-ide-debugger-python'), - }, - ], - [ - 'react-native', - { - executable: { - command: 'node', - args: [ - nuclideUri.join( - resolvePackagePath('atom-ide-debugger-react-native'), - 'VendorLib/vscode-react-native/out/debugger/reactNativeDebugEntryPoint.js', - ), - ], - }, - root: resolvePackagePath('atom-ide-debugger-react-native'), - }, - ], - [ - 'prepack', - { - executable: { - command: 'node', - args: [ - nuclideUri.join( - __dirname, - 'VendorLib/vscode-prepack/adapter/DebugAdapter.js', - ), - ], - }, - root: nuclideUri.join(__dirname, 'VendorLib/vscode-prepack'), - }, - ], - [ - 'ocaml', - { - executable: { - command: 'node', - args: [ - nuclideUri.join( - resolvePackagePath('atom-ide-debugger-ocaml'), - 'lib/vscode-debugger-entry.js', - ), - ], - }, - root: resolvePackagePath('atom-ide-debugger-ocaml'), - }, - ], - [ - 'native_gdb', - { - executable: { - command: 'node', - args: [ - nuclideUri.join( - resolvePackagePath('atom-ide-debugger-native-gdb'), - 'lib/RunTranspiledServer.js', - ), - ], - }, - root: resolvePackagePath('atom-ide-debugger-native-gdb'), - }, - ], - [ - 'native_lldb', - { - executable: { - command: 'lldb-vscode', - args: [], - }, - root: nuclideUri.join(__dirname, 'fb-native-debugger-lldb-vsp'), - }, - ], - [ - 'hhvm', - { - executable: { - command: 'node', - args: [ - nuclideUri.join( - __dirname, - '../../pkg/nuclide-debugger-hhvm-rpc/lib/hhvmWrapper.js', - ), - ], - }, - root: nuclideUri.join(__dirname, '../../pkg/nuclide-debugger-hhvm-rpc'), - }, - ], - [ - 'mobilejs', - { - executable: { - command: 'node', - args: [ - nuclideUri.join( - __dirname, - '../../pkg/fb-debugger-mobilejs-rpc/lib/vscode/vscode-debugger-entry.js', - ), - ], - }, - root: nuclideUri.join(__dirname, '../../pkg/fb-debugger-mobilejs-rpc'), - }, - ], -]); - -export function getAdapterExecutable( - adapter: VsAdapterType, -): VSAdapterExecutableInfo { - const adapterInfo = _adapters.get(adapter); - if (adapterInfo == null) { - throw new Error(`Cannot find VSP for given adapter type ${adapter}`); - } - return adapterInfo.executable; -} - -export function getAdapterPackageRoot(adapter: VsAdapterType): string { - const adapterInfo = _adapters.get(adapter); - if (adapterInfo == null) { - throw new Error(`Cannot find VSP for given adapter type ${adapter}`); - } - return adapterInfo.root; -} +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +getAdapterExecutable = getAdapterExecutable;exports. + + + + + + + + + +getAdapterPackageRoot = getAdapterPackageRoot;var _nuclideUri;function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));}var _fs = _interopRequireDefault(require('fs'));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} /** + * 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. + * + * + * @format + */const modulesPath = (_nuclideUri || _load_nuclideUri()).default.dirname(__dirname);function resolvePackagePath(packageName) {const bundledPath = (_nuclideUri || _load_nuclideUri()).default.join(modulesPath, packageName);if (_fs.default.existsSync(bundledPath)) {return bundledPath;} else if (typeof atom !== 'undefined') {const pkg = atom.packages.getActivePackage(packageName);if (pkg != null) {return (_nuclideUri || _load_nuclideUri()).default.join(pkg.path, 'node_modules', packageName);}}return 'DEBUGGER_RUNTIME_NOT_FOUND';}const _adapters = new Map([['node', { executable: { command: 'node', args: [(_nuclideUri || _load_nuclideUri()).default.join(resolvePackagePath('atom-ide-debugger-node'), 'VendorLib/vscode-node-debug2/out/src/nodeDebug.js')] }, root: resolvePackagePath('atom-ide-debugger-node') }], ['python', { executable: { command: 'node', args: [(_nuclideUri || _load_nuclideUri()).default.join(resolvePackagePath('atom-ide-debugger-python'), 'VendorLib/vs-py-debugger/out/client/debugger/Main.js')] }, root: resolvePackagePath('atom-ide-debugger-python') }], ['react-native', { executable: { command: 'node', args: [(_nuclideUri || _load_nuclideUri()).default.join(resolvePackagePath('atom-ide-debugger-react-native'), 'VendorLib/vscode-react-native/out/debugger/reactNativeDebugEntryPoint.js')] }, root: resolvePackagePath('atom-ide-debugger-react-native') }], ['prepack', { executable: { command: 'node', args: [(_nuclideUri || _load_nuclideUri()).default.join(__dirname, 'VendorLib/vscode-prepack/adapter/DebugAdapter.js')] }, root: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, 'VendorLib/vscode-prepack') }], ['ocaml', { executable: { command: 'node', args: [(_nuclideUri || _load_nuclideUri()).default.join(resolvePackagePath('atom-ide-debugger-ocaml'), 'lib/vscode-debugger-entry.js')] }, root: resolvePackagePath('atom-ide-debugger-ocaml') }], ['native_gdb', { executable: { command: 'node', args: [(_nuclideUri || _load_nuclideUri()).default.join(resolvePackagePath('atom-ide-debugger-native-gdb'), 'lib/RunTranspiledServer.js')] }, root: resolvePackagePath('atom-ide-debugger-native-gdb') }], ['native_lldb', { executable: { command: 'lldb-vscode', args: [] }, root: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, 'fb-native-debugger-lldb-vsp') }], ['hhvm', { executable: { command: 'node', args: [(_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../../pkg/nuclide-debugger-hhvm-rpc/lib/hhvmWrapper.js')] }, root: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../../pkg/nuclide-debugger-hhvm-rpc') }], ['mobilejs', { executable: { command: 'node', args: [(_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../../pkg/fb-debugger-mobilejs-rpc/lib/vscode/vscode-debugger-entry.js')] }, root: (_nuclideUri || _load_nuclideUri()).default.join(__dirname, '../../pkg/fb-debugger-mobilejs-rpc') }]]);function getAdapterExecutable(adapter) {const adapterInfo = _adapters.get(adapter);if (adapterInfo == null) {throw new Error(`Cannot find VSP for given adapter type ${adapter}`);}return adapterInfo.executable;}function getAdapterPackageRoot(adapter) {const adapterInfo = _adapters.get(adapter);if (adapterInfo == null) {throw new Error(`Cannot find VSP for given adapter type ${adapter}`);}return adapterInfo.root;} \ No newline at end of file diff --git a/modules/nuclide-debugger-common/main.js b/modules/nuclide-debugger-common/main.js index 89665794..5e3f771f 100644 --- a/modules/nuclide-debugger-common/main.js +++ b/modules/nuclide-debugger-common/main.js @@ -1,53 +1,53 @@ -/** - * 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 - * @format - */ - -export type { - AtomNotificationType, - ControlButtonSpecification, - DebuggerCapabilities, - DebuggerConfigAction, - DebuggerConfigurationProvider, - DebuggerProperties, - IProcessConfig, - IVspInstance, - MessageProcessor, - NuclideDebuggerProvider, - VSAdapterExecutableInfo, - VsAdapterType, -} from './types'; - -export { - getVSCodeDebuggerAdapterServiceByNuclideUri, -} from './debug-adapter-service'; - -export { - default as DebuggerLaunchAttachProvider, -} from './DebuggerLaunchAttachProvider'; - -export {default as VsDebugSession} from './VsDebugSession'; - -export {default as VspProcessInfo} from './VspProcessInfo'; - -export {VsAdapterTypes} from './constants'; - -export { - deserializeDebuggerConfig, - serializeDebuggerConfig, -} from './DebuggerConfigSerializer'; - -export { - localToRemoteProcessor, - pathProcessor, - remoteToLocalProcessor, -} from './processors'; - -export {default as VsAdapterSpawner} from './VsAdapterSpawner'; +'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _debugAdapterService;function _load_debugAdapterService() {return _debugAdapterService = require('./debug-adapter-service');}Object.defineProperty(exports, 'getVSCodeDebuggerAdapterServiceByNuclideUri', { enumerable: true, get: function () {return (_debugAdapterService || _load_debugAdapterService()). + + + + + + + + + + + + + + + + + + + + + + + + + + + + getVSCodeDebuggerAdapterServiceByNuclideUri;} });var _DebuggerLaunchAttachProvider;function _load_DebuggerLaunchAttachProvider() {return _DebuggerLaunchAttachProvider = require('./DebuggerLaunchAttachProvider');}Object.defineProperty(exports, 'DebuggerLaunchAttachProvider', { enumerable: true, get: function () {return _interopRequireDefault(_DebuggerLaunchAttachProvider || _load_DebuggerLaunchAttachProvider()). + + + + default;} });var _VsDebugSession;function _load_VsDebugSession() {return _VsDebugSession = require('./VsDebugSession');}Object.defineProperty(exports, 'VsDebugSession', { enumerable: true, get: function () {return _interopRequireDefault(_VsDebugSession || _load_VsDebugSession()). + + + default;} });var _VspProcessInfo;function _load_VspProcessInfo() {return _VspProcessInfo = require('./VspProcessInfo');}Object.defineProperty(exports, 'VspProcessInfo', { enumerable: true, get: function () {return _interopRequireDefault(_VspProcessInfo || _load_VspProcessInfo()). + + default;} });var _constants;function _load_constants() {return _constants = require('./constants');}Object.defineProperty(exports, 'VsAdapterTypes', { enumerable: true, get: function () {return (_constants || _load_constants()). + + VsAdapterTypes;} });var _DebuggerConfigSerializer;function _load_DebuggerConfigSerializer() {return _DebuggerConfigSerializer = require('./DebuggerConfigSerializer');}Object.defineProperty(exports, 'deserializeDebuggerConfig', { enumerable: true, get: function () {return (_DebuggerConfigSerializer || _load_DebuggerConfigSerializer()). + + + deserializeDebuggerConfig;} });Object.defineProperty(exports, 'serializeDebuggerConfig', { enumerable: true, get: function () {return (_DebuggerConfigSerializer || _load_DebuggerConfigSerializer()). + serializeDebuggerConfig;} });var _processors;function _load_processors() {return _processors = require('./processors');}Object.defineProperty(exports, 'localToRemoteProcessor', { enumerable: true, get: function () {return (_processors || _load_processors()). + + + + localToRemoteProcessor;} });Object.defineProperty(exports, 'pathProcessor', { enumerable: true, get: function () {return (_processors || _load_processors()). + pathProcessor;} });Object.defineProperty(exports, 'remoteToLocalProcessor', { enumerable: true, get: function () {return (_processors || _load_processors()). + remoteToLocalProcessor;} });var _VsAdapterSpawner;function _load_VsAdapterSpawner() {return _VsAdapterSpawner = require('./VsAdapterSpawner');}Object.defineProperty(exports, 'VsAdapterSpawner', { enumerable: true, get: function () {return _interopRequireDefault(_VsAdapterSpawner || _load_VsAdapterSpawner()). + + + default;} });function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} \ No newline at end of file diff --git a/modules/nuclide-debugger-common/processors.js b/modules/nuclide-debugger-common/processors.js index e19643d3..f25ffb15 100644 --- a/modules/nuclide-debugger-common/processors.js +++ b/modules/nuclide-debugger-common/processors.js @@ -1,54 +1,54 @@ -/** - * 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 - * @format - */ - -import type {MessageProcessor} from './types'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; - -import nuclideUri from 'nuclide-commons/nuclideUri'; - -type PathMapper = (path: string) => string; - -export function remoteToLocalProcessor(): MessageProcessor { - return pathProcessor(path => nuclideUri.getPath(path)); -} +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports. -export function localToRemoteProcessor( - targetUri: NuclideUri, -): MessageProcessor { - const hostname = nuclideUri.getHostname(targetUri); - return pathProcessor(path => nuclideUri.createRemoteUri(hostname, path)); -} -export function pathProcessor(pathMapper: PathMapper): MessageProcessor { - return message => { - processRequestsUris(message, pathMapper); - processResponseUris(message, pathMapper); - processEventsUris(message, pathMapper); - }; -} -function processRequestsUris(message: Object, pathMapper: PathMapper): void { - if (message.type !== 'request') { - return; + + + + + + + + + + + + + + + +remoteToLocalProcessor = remoteToLocalProcessor;exports. + + + +localToRemoteProcessor = localToRemoteProcessor;exports. + + + + + + +pathProcessor = pathProcessor;var _nuclideUri;function _load_nuclideUri() {return _nuclideUri = _interopRequireDefault(require('nuclide-commons/nuclideUri'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function remoteToLocalProcessor() {return pathProcessor(path => (_nuclideUri || _load_nuclideUri()).default.getPath(path));} /** + * 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. + * + * + * @format + */function localToRemoteProcessor(targetUri) {const hostname = (_nuclideUri || _load_nuclideUri()).default.getHostname(targetUri);return pathProcessor(path => (_nuclideUri || _load_nuclideUri()).default.createRemoteUri(hostname, path));}function pathProcessor(pathMapper) {return message => {processRequestsUris(message, pathMapper);processResponseUris(message, pathMapper);processEventsUris(message, pathMapper);};}function processRequestsUris(message, pathMapper) {if (message.type !== 'request') {return; } switch (message.command) { case 'setBreakpoints': case 'source': translateField(message, 'arguments.source.path', pathMapper); - break; - } + break;} + } -function processResponseUris(message: Object, pathMapper: PathMapper): void { +function processResponseUris(message, pathMapper) { if (message.type !== 'response') { return; } @@ -56,28 +56,28 @@ function processResponseUris(message: Object, pathMapper: PathMapper): void { case 'setBreakpoints': case 'setFunctionBreakpoints': message.body.breakpoints.forEach(bp => - translateField(bp, 'source.path', pathMapper), - ); + translateField(bp, 'source.path', pathMapper)); + break; case 'stackTrace': message.body.stackFrames.forEach(frame => - translateField(frame, 'source.path', pathMapper), - ); + translateField(frame, 'source.path', pathMapper)); + break; case 'modules': message.body.modules.forEach(module => - translateField(module, 'path', pathMapper), - ); + translateField(module, 'path', pathMapper)); + break; case 'loadedSources': message.body.sources.forEach(source => - translateField(source, 'path', pathMapper), - ); - break; - } + translateField(source, 'path', pathMapper)); + + break;} + } -function processEventsUris(message: Object, pathMapper: PathMapper): void { +function processEventsUris(message, pathMapper) { if (message.type !== 'event') { return; } @@ -92,17 +92,17 @@ function processEventsUris(message: Object, pathMapper: PathMapper): void { break; case 'module': translateField(message, 'body.module.path', pathMapper); - break; - } + break;} + } // Traverse the source `object` for a deeply nested field, // then apply the `pathMapper` to that field, if existing. function translateField( - object: Object, - fieldDescriptor: string, - pathMapper: PathMapper, -): void { +object, +fieldDescriptor, +pathMapper) +{ const fields = fieldDescriptor.split('.'); let lastObj = {}; const value = fields.reduce((child, field) => { @@ -115,6 +115,6 @@ function translateField( }, object); if (value != null) { const [lastField] = fields.slice(-1); - lastObj[lastField] = pathMapper((value: any)); + lastObj[lastField] = pathMapper(value); } -} +} \ No newline at end of file diff --git a/modules/nuclide-debugger-common/types.js b/modules/nuclide-debugger-common/types.js index e72c1477..d7c8d073 100644 --- a/modules/nuclide-debugger-common/types.js +++ b/modules/nuclide-debugger-common/types.js @@ -1,164 +1,19 @@ -/** - * 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 - * @format - */ - -import type DebuggerLaunchAttachProvider from './DebuggerLaunchAttachProvider'; -import type {Observable, ConnectableObservable} from 'rxjs'; -import type {NuclideUri} from 'nuclide-commons/nuclideUri'; -import type {IconName} from 'nuclide-commons-ui/Icon'; -import type {ProcessMessage} from 'nuclide-commons/process'; -import * as DebugProtocol from 'vscode-debugprotocol'; -import * as React from 'react'; - -export interface IVspInstance { - customRequest( - request: string, - args: any, - ): Promise; - observeCustomEvents(): Observable; -} - -export type AtomNotificationType = 'info' | 'warning' | 'error' | 'fatalError'; - -export type DebuggerConfigAction = 'launch' | 'attach'; - -export type VSAdapterExecutableInfo = { - command: string, - args: Array, -}; - -export type NativeVsAdapterType = 'native_lldb' | 'native_gdb'; - -export type VsAdapterType = - | 'hhvm' - | 'python' - | 'node' - | 'java' - | 'react-native' - | 'prepack' - | 'ocaml' - | 'mobilejs' - | 'native_lldb' - | 'native_gdb'; - -export type NuclideDebuggerProvider = { - name: string, - getLaunchAttachProvider( - connection: NuclideUri, - ): ?DebuggerLaunchAttachProvider, -}; - -export type ControlButtonSpecification = { - icon: IconName, - title?: string, - onClick: () => mixed, -}; - -// Indicates which of various optional features that this debugger supports. -export type DebuggerCapabilities = { - +threads: boolean, -}; - -// Describes how to configure various properties that individual debuggers -// are allowed to override. -export type DebuggerProperties = { - +customControlButtons: Array, - +threadsComponentTitle: string, -}; - -export type IProcessConfig = {| - +targetUri: NuclideUri, - +debugMode: DebuggerConfigAction, - +adapterType: VsAdapterType, - +adapterExecutable: ?VSAdapterExecutableInfo, - // TODO(most): deprecate - +capabilities: DebuggerCapabilities, - // TODO(most): deprecate - +properties: DebuggerProperties, - +config: Object, - +clientPreprocessor?: ?MessageProcessor, - +adapterPreprocessor?: ?MessageProcessor, -|}; - -export interface IVsAdapterSpawner { - spawnAdapter( - adapter: VSAdapterExecutableInfo, - ): ConnectableObservable; - write(input: string): Promise; -} - -export type MessageProcessor = (message: Object) => void; - -export type AutoGenPropertyPrimitiveType = 'string' | 'number' | 'boolean'; - -export type AutoGenPropertyType = - | AutoGenPropertyPrimitiveType - | 'array' - | 'enum' - | 'object' - | 'json' - | 'process'; - -export type AutoGenProperty = { - name: string, - type: AutoGenPropertyType, - itemType?: AutoGenPropertyPrimitiveType, - description: string, - defaultValue?: any, - required: boolean, - visible: boolean, - enums?: string[], - enumsDefaultValue?: string, -}; - -export type ResolveConfig = (config: Object) => Promise; - -type AutoGenLaunchOrAttachConfigBase = { - // General Properties - properties: AutoGenProperty[], - threads: boolean, - vsAdapterType: VsAdapterType, - cwdPropertyName?: ?string, - scriptExtension?: string, - scriptPropertyName?: ?string, - header?: React.Node, -}; - -export type AutoGenLaunchConfig = AutoGenLaunchOrAttachConfigBase & { - // Disjoint Union Flag - launch: true, - // Launch Specific Properties -}; - -export type AutoGenAttachConfig = AutoGenLaunchOrAttachConfigBase & { - // Disjoint Union Flag - launch: false, - // General Properties - // Attach Specific Properties -}; - -export type AutoGenLaunchOrAttachConfig = - | AutoGenLaunchConfig - | AutoGenAttachConfig; - -export type AutoGenConfig = {| - launch: ?AutoGenLaunchConfig, - attach: ?AutoGenAttachConfig, -|}; - -export type LaunchAttachProviderIsEnabled = ( - action: DebuggerConfigAction, - config: AutoGenConfig, -) => Promise; - -export interface DebuggerConfigurationProvider { - resolveConfiguration(configuration: IProcessConfig): Promise; -} +'use strict';var _vscodeDebugprotocol; + + + + + + + + + + + + + + + + +function _load_vscodeDebugprotocol() {return _vscodeDebugprotocol = _interopRequireWildcard(require('vscode-debugprotocol'));} +var _react = _interopRequireWildcard(require('react'));function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj.default = obj;return newObj;}} \ No newline at end of file diff --git a/modules/nuclide-jasmine/lib/faketimer.js b/modules/nuclide-jasmine/lib/faketimer.js index 0334965f..e32f59d8 100644 --- a/modules/nuclide-jasmine/lib/faketimer.js +++ b/modules/nuclide-jasmine/lib/faketimer.js @@ -1,20 +1,20 @@ -/** - * 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 - * @format - */ +'use strict'; /** + * 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. + * + * + * @format + */ /** - * Port of Atom's timer utils (https://fburl.com/104714454) which is useful for unittest. - * Use fakeSetTimeout, fakeClearTimeout, fakeSetInterval and fakeClearInterval to mock Node.js's - * Timer utils, and using advanceClock to advance the fake timer to trigger timed callback. - */ + * Port of Atom's timer utils (https://fburl.com/104714454) which is useful for unittest. + * Use fakeSetTimeout, fakeClearTimeout, fakeSetInterval and fakeClearInterval to mock Node.js's + * Timer utils, and using advanceClock to advance the fake timer to trigger timed callback. + */ require('jasmine-node'); // eslint-disable-line rulesdir/no-commonjs let now = 0; @@ -23,7 +23,7 @@ let intervalCount = 0; let timeouts = []; let intervalTimeouts = {}; -function resetTimeouts(): void { +function resetTimeouts() { now = 0; timeoutCount = 0; intervalCount = 0; @@ -31,20 +31,20 @@ function resetTimeouts(): void { intervalTimeouts = {}; } -function fakeSetTimeout(callback: () => ?any, ms: number): number { +function fakeSetTimeout(callback, ms) { const id = ++timeoutCount; timeouts.push([id, now + ms, callback]); timeouts.sort( - ([, strikeTime0], [, strikeTime1]) => strikeTime0 - strikeTime1, - ); + ([, strikeTime0], [, strikeTime1]) => strikeTime0 - strikeTime1); + return id; } -function fakeClearTimeout(idToClear: number): void { +function fakeClearTimeout(idToClear) { timeouts = timeouts.filter(([id]) => id !== idToClear); } -function fakeSetInterval(callback: () => ?any, ms: number): number { +function fakeSetInterval(callback, ms) { const id = ++intervalCount; const action = () => { callback(); @@ -54,11 +54,11 @@ function fakeSetInterval(callback: () => ?any, ms: number): number { return id; } -function fakeClearInterval(idToClear: number): void { +function fakeClearInterval(idToClear) { fakeClearTimeout(intervalTimeouts[idToClear]); } -function advanceClock(deltaMs: number): void { +function advanceClock(deltaMs) { const advanceTo = now + deltaMs; while (timeouts.length !== 0 && timeouts[0][1] <= advanceTo) { @@ -71,19 +71,19 @@ function advanceClock(deltaMs: number): void { } /** - * Allows tests to use the non-fake setTimeout and clearTimeout functions. - */ -function useRealClock(): void { + * Allows tests to use the non-fake setTimeout and clearTimeout functions. + */ +function useRealClock() { jasmine.unspy(global, 'setTimeout'); jasmine.unspy(global, 'clearTimeout'); jasmine.unspy(Date, 'now'); } /** - * Atom does this half-way mock. - * https://github.com/atom/atom/blob/v1.12.7/spec/spec-helper.coffee#L169-L174 - */ -function useMockClock(): void { + * Atom does this half-way mock. + * https://github.com/atom/atom/blob/v1.12.7/spec/spec-helper.coffee#L169-L174 + */ +function useMockClock() { spyOn(global, 'setInterval').andCallFake(fakeSetInterval); spyOn(global, 'clearInterval').andCallFake(fakeClearInterval); } @@ -98,16 +98,16 @@ global.advanceClock = advanceClock; jasmine.useRealClock = useRealClock; jasmine.useMockClock = useMockClock; // $FlowIssue: https://github.com/facebook/flow/issues/285 -Object.defineProperty(global, 'now', {get: () => now}); +Object.defineProperty(global, 'now', { get: () => now }); /** - * This hook is a the first initialization code that happens before any jasmine test case is - * executed. This allows to use the fake timing by default and is a direct port from Atom's - * `spec-helper.coffee` - */ + * This hook is a the first initialization code that happens before any jasmine test case is + * executed. This allows to use the fake timing by default and is a direct port from Atom's + * `spec-helper.coffee` + */ beforeEach(() => { resetTimeouts(); spyOn(Date, 'now').andCallFake(() => now); spyOn(global, 'setTimeout').andCallFake(fakeSetTimeout); spyOn(global, 'clearTimeout').andCallFake(fakeClearTimeout); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-jasmine/lib/focused.js b/modules/nuclide-jasmine/lib/focused.js index 66fd4ce5..a681079b 100644 --- a/modules/nuclide-jasmine/lib/focused.js +++ b/modules/nuclide-jasmine/lib/focused.js @@ -1,3 +1,27 @@ +'use strict'; + + + + + + + + + + + + + + + + + + +// eslint-disable-next-line rulesdir/no-commonjs +require('jasmine-node'); + +// These are undocumented APIs. The type of jasmine is redefined here, so that +// we don't pollute the real lib def with this nonsense. /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. @@ -6,36 +30,12 @@ * 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 + * * @format - */ - -/** - * A port of Atom's focused specs. - * https://github.com/atom/jasmine-focused/blob/c922330/src/jasmine-focused.coffee - */ - -import invariant from 'assert'; - -// eslint-disable-next-line rulesdir/no-commonjs -require('jasmine-node'); - -// These are undocumented APIs. The type of jasmine is redefined here, so that -// we don't pollute the real lib def with this nonsense. -const jasmine: { - getEnv(): { - focusPriority?: number, - specFilter?: (spec: any) => boolean, - }, - Env: { - prototype: { - ddescribe?: () => void, - iit?: () => void, - }, - }, -} = - global.jasmine; - + */ /** + * A port of Atom's focused specs. + * https://github.com/atom/jasmine-focused/blob/c922330/src/jasmine-focused.coffee + */const jasmine = global.jasmine; function setGlobalFocusPriority(priority) { const env = jasmine.getEnv(); // flowlint-next-line sketchy-null-number:off @@ -50,8 +50,8 @@ function setGlobalFocusPriority(priority) { function fdescribe(description, specDefinitions, priority_) { const priority = priority_ != null ? priority_ : 1; setGlobalFocusPriority(priority); - const suite = describe(description, specDefinitions); - invariant(suite != null); + const suite = describe(description, specDefinitions);if (!( + suite != null)) {throw new Error('Invariant violation: "suite != null"');} suite.focusPriority = priority; return suite; } @@ -70,8 +70,8 @@ global.fffdescribe = fffdescribe; function fit(description, definition, priority_) { const priority = priority_ != null ? priority_ : 1; setGlobalFocusPriority(priority); - const spec = it(description, definition); - invariant(spec != null); + const spec = it(description, definition);if (!( + spec != null)) {throw new Error('Invariant violation: "spec != null"');} spec.focusPriority = priority; return spec; } @@ -87,7 +87,7 @@ function fffit(description, specDefinitions) { } global.fffit = fffit; -jasmine.getEnv().specFilter = function(spec) { +jasmine.getEnv().specFilter = function (spec) { const env = jasmine.getEnv(); const globalFocusPriority = env.focusPriority; const parent = spec.parentSuite != null ? spec.parentSuite : spec.suite; @@ -98,8 +98,8 @@ jasmine.getEnv().specFilter = function(spec) { return true; } else if (!parent) { return false; - } else { - invariant(typeof env.specFilter === 'function'); + } else {if (!( + typeof env.specFilter === 'function')) {throw new Error('Invariant violation: "typeof env.specFilter === \'function\'"');} return env.specFilter(parent); } }; @@ -111,4 +111,4 @@ if (typeof jasmine.Env.prototype.ddescribe === 'function') { if (typeof jasmine.Env.prototype.iit === 'function') { delete jasmine.Env.prototype.iit; -} +} \ No newline at end of file diff --git a/modules/nuclide-jasmine/lib/unspy.js b/modules/nuclide-jasmine/lib/unspy.js index ea251801..7caccd2f 100644 --- a/modules/nuclide-jasmine/lib/unspy.js +++ b/modules/nuclide-jasmine/lib/unspy.js @@ -1,25 +1,25 @@ -/** - * 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 - * @format - */ +'use strict'; /** + * 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. + * + * + * @format + */ // eslint-disable-next-line rulesdir/no-commonjs require('jasmine-node'); /** - * unspy is a ported utility from Atom's `spec-helper.coffee` that restores the - * jasmine spied function on an object to its original value. - */ -jasmine.unspy = function unspy(object: Object, methodName: string) { + * unspy is a ported utility from Atom's `spec-helper.coffee` that restores the + * jasmine spied function on an object to its original value. + */ +jasmine.unspy = function unspy(object, methodName) { if (!object[methodName].hasOwnProperty('originalValue')) { throw new Error('Not a spy ' + methodName); } object[methodName] = object[methodName].originalValue; -}; +}; \ No newline at end of file diff --git a/modules/nuclide-jasmine/lib/waitsForPromise.js b/modules/nuclide-jasmine/lib/waitsForPromise.js index c6dd0b7d..ba54af57 100644 --- a/modules/nuclide-jasmine/lib/waitsForPromise.js +++ b/modules/nuclide-jasmine/lib/waitsForPromise.js @@ -1,25 +1,25 @@ -/** - * 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 - * @format - */ - -import invariant from 'assert'; - -type WaitsForPromiseOptions = { - shouldReject?: boolean, - timeout?: number, -}; - -export default function waitsForPromise( - ...args: Array Promise)> -): void { +'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default = + + + + + + + + + + + + + + + + + + +waitsForPromise;function waitsForPromise( +...args) +{ let shouldReject; let timeout; if (args.length > 1) { @@ -33,46 +33,56 @@ export default function waitsForPromise( let finished = false; runs(() => { - const fn = args[args.length - 1]; - invariant(typeof fn === 'function'); + const fn = args[args.length - 1];if (!( + typeof fn === 'function')) {throw new Error('Invariant violation: "typeof fn === \'function\'"');} const promise = fn(); if (shouldReject) { - promise - .then( - () => { - jasmine - .getEnv() - .currentSpec.fail( - 'Expected promise to be rejected, but it was resolved', - ); - }, - () => { - // Do nothing, it's expected. - }, - ) - .then(() => { - finished = true; - }); + promise. + then( + () => { + jasmine. + getEnv(). + currentSpec.fail( + 'Expected promise to be rejected, but it was resolved'); + + }, + () => { + // Do nothing, it's expected. + }). + + then(() => { + finished = true; + }); } else { - promise - .then( - () => { - // Do nothing, it's expected. - }, - error => { - const text = error ? error.stack || error.toString() : 'undefined'; - jasmine - .getEnv() - .currentSpec.fail( - `Expected promise to be resolved, but it was rejected with ${text}`, - ); - }, - ) - .then(() => { - finished = true; - }); + promise. + then( + () => { + // Do nothing, it's expected. + }, + error => { + const text = error ? error.stack || error.toString() : 'undefined'; + jasmine. + getEnv(). + currentSpec.fail( + `Expected promise to be resolved, but it was rejected with ${text}`); + + }). + + then(() => { + finished = true; + }); } }); waitsFor(timeout, () => finished); -} +} /** + * 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. + * + * + * @format + */ \ No newline at end of file diff --git a/modules/nuclide-jasmine/spec/faketimer-spec.js b/modules/nuclide-jasmine/spec/faketimer-spec.js index 71ba2923..5f098482 100644 --- a/modules/nuclide-jasmine/spec/faketimer-spec.js +++ b/modules/nuclide-jasmine/spec/faketimer-spec.js @@ -1,14 +1,14 @@ -/** - * 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 - * @format - */ +'use strict'; /** + * 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. + * + * + * @format + */ describe('Fake timer test suite', () => { it('test setTimeout and clearTimeout', () => { @@ -152,4 +152,4 @@ describe('Fake timer test suite', () => { expect(now2 - now1).toEqual(100); expect(now2).toEqual(global.now); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-jasmine/spec/run-jasmine-tests-spec.js b/modules/nuclide-jasmine/spec/run-jasmine-tests-spec.js index 0a783d36..869b3639 100644 --- a/modules/nuclide-jasmine/spec/run-jasmine-tests-spec.js +++ b/modules/nuclide-jasmine/spec/run-jasmine-tests-spec.js @@ -1,30 +1,30 @@ -/** - * 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 - * @format - */ - -import waitsForPromise from '../lib/waitsForPromise'; - -function testFlowtypedFunction(arg: number): number { - return arg; -} +'use strict';var _asyncToGenerator = _interopRequireDefault(require('async-to-generator'));var _waitsForPromise; + + + + + + -describe('Jasmine transpile test suite', () => { - it('test transpiler worked as exepcted', () => { - const promise = Promise.resolve('test'); - expect(typeof promise).toEqual('object'); - expect(testFlowtypedFunction(1)).toEqual(1); - }); -}); -describe('Jasmine environment', () => { + + + +function _load_waitsForPromise() {return _waitsForPromise = _interopRequireDefault(require('../lib/waitsForPromise'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +function testFlowtypedFunction(arg) { + return arg; +} /** + * 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. + * + * + * @format + */describe('Jasmine transpile test suite', () => {it('test transpiler worked as exepcted', () => {const promise = Promise.resolve('test');expect(typeof promise).toEqual('object');expect(testFlowtypedFunction(1)).toEqual(1);});});describe('Jasmine environment', () => { it('sets the correct NODE_ENV', () => { expect(process.env.NODE_ENV).toEqual('test'); }); @@ -34,25 +34,25 @@ describe('Jasmine waitsForPromise test suite', () => { beforeEach(() => jasmine.useRealClock()); it('test waitsForPromise worked as expected on a resolved promise', () => { - waitsForPromise(async () => { + (0, (_waitsForPromise || _load_waitsForPromise()).default)((0, _asyncToGenerator.default)(function* () { const promise = Promise.resolve('test'); - const result = await promise; + const result = yield promise; expect(result).toEqual('test'); - }); + })); }); it('test waitsForPromise worked as expected on a rejected promise', () => { - waitsForPromise({shouldReject: true}, () => - Promise.reject(new Error('test')), - ); + (0, (_waitsForPromise || _load_waitsForPromise()).default)({ shouldReject: true }, () => + Promise.reject(new Error('test'))); + }); it('test waitsForPromise worked as expected on a customized timeout', () => { // This is more than default timeout of 5 seconds. - waitsForPromise({shouldReject: false, timeout: 7 * 1000}, () => { + (0, (_waitsForPromise || _load_waitsForPromise()).default)({ shouldReject: false, timeout: 7 * 1000 }, () => { return new Promise((resolve, reject) => { setTimeout(resolve, 6 * 1000); }); }); }); -}); +}); \ No newline at end of file diff --git a/modules/nuclide-jest/atom-reporter.js b/modules/nuclide-jest/atom-reporter.js index 6809ee30..60df1e15 100644 --- a/modules/nuclide-jest/atom-reporter.js +++ b/modules/nuclide-jest/atom-reporter.js @@ -1,62 +1,61 @@ -/** - * 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 - * @format - */ - -import type {TestResult, AggregatedResults} from './types'; - -import UniversalDisposable from 'nuclide-commons/UniversalDisposable'; -import React from 'react'; -import ReactDOM from 'react-dom'; -import nullthrows from 'nullthrows'; - -import Model from 'nuclide-commons/Model'; -import Jest from './frontend/Jest'; - -const div = document.createElement('div'); -nullthrows(document.body).appendChild(div); - -type GlobalConfig = Object; - -// Jest seems to be particular about this being a commonjs export +'use strict';var _UniversalDisposable; + + + + + + + + + + + + + +function _load_UniversalDisposable() {return _UniversalDisposable = _interopRequireDefault(require('nuclide-commons/UniversalDisposable'));} +var _react = _interopRequireDefault(require('react')); +var _reactDom = _interopRequireDefault(require('react-dom'));var _nullthrows; +function _load_nullthrows() {return _nullthrows = _interopRequireDefault(require('nullthrows'));}var _Model; + +function _load_Model() {return _Model = _interopRequireDefault(require('nuclide-commons/Model'));}var _Jest; +function _load_Jest() {return _Jest = _interopRequireDefault(require('./frontend/Jest'));}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };} + +const div = document.createElement('div'); /** + * 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. + * + * + * @format + */(0, (_nullthrows || _load_nullthrows()).default)(document.body).appendChild(div); // Jest seems to be particular about this being a commonjs export // eslint-disable-next-line rulesdir/no-commonjs module.exports = class AtomReporter { - _modelSubscription: UniversalDisposable; - _globalConfig: Object; - _options: Object; - model: Model<{ - results: ?AggregatedResults, - }>; - - constructor(globalConfig: GlobalConfig, options: Object) { + + + constructor(globalConfig, options) { this._globalConfig = globalConfig; this._options = options; - this.model = new Model({results: null}); - this._modelSubscription = new UniversalDisposable( - this.model.subscribe(state => { - ReactDOM.render(, div); - }), - ); + this.model = new (_Model || _load_Model()).default({ results: null }); + this._modelSubscription = new (_UniversalDisposable || _load_UniversalDisposable()).default( + this.model.subscribe(state => { + _reactDom.default.render(_react.default.createElement((_Jest || _load_Jest()).default, { results: state.results }), div); + })); + } onTestResult( - config: GlobalConfig, - result: TestResult, - results: AggregatedResults, - ) { - this.model.setState({results}); + config, + result, + results) + { + this.model.setState({ results }); } - onRunComplete(contexts: mixed, results: AggregatedResults) { - this.model.setState({results}); + onRunComplete(contexts, results) { + this.model.setState({ results }); this._modelSubscription.dispose(); - } -}; + }}; \ No newline at end of file diff --git a/modules/nuclide-jest/emptyObject.js b/modules/nuclide-jest/emptyObject.js index 9fed47f5..39e9e21e 100644 --- a/modules/nuclide-jest/emptyObject.js +++ b/modules/nuclide-jest/emptyObject.js @@ -1,14 +1,14 @@ -/** - * 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 - * @format - */ +"use strict"; /** + * 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. + * + * + * @format + */ // eslint-disable-next-line rulesdir/no-commonjs -module.exports = {}; +module.exports = {}; \ No newline at end of file diff --git a/modules/nuclide-jest/frontend/Jest.js b/modules/nuclide-jest/frontend/Jest.js index b7b3d16d..9badd2f4 100644 --- a/modules/nuclide-jest/frontend/Jest.js +++ b/modules/nuclide-jest/frontend/Jest.js @@ -1,167 +1,166 @@ -/** - * 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 - * @format - */ - -import type {AggregatedResults, TestResult, AssertionResult} from '../types'; - -import React from 'react'; - -import {Icon} from 'nuclide-commons-ui/Icon'; - -type Props = { - results: ?AggregatedResults, -}; +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); + + + + + + + + + + + + + +var _react = _interopRequireDefault(require('react'));var _Icon; -export default class Jest extends React.Component { - render() { - const {results} = this.props; - if (results == null) { - return null; +function _load_Icon() {return _Icon = require('nuclide-commons-ui/Icon');}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _objectWithoutProperties(obj, keys) {var target = {};for (var i in obj) {if (keys.indexOf(i) >= 0) continue;if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;target[i] = obj[i];}return target;} /** + * 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. + * + * + * @format + */class Jest extends _react.default.Component {render() {const { results } = this.props;if (results == null) {return null; } const success = results.numFailedTests === 0; return ( - -
    - {success ? 'Passed!' : 'Failed :('} -
    - {results.numPassedTests} of {results.numTotalTests} passed -
    -
    -
    - - {results.testResults.map(result => ( - - ))} - -
    - Raw Jest JSON Output (debug) -
    {JSON.stringify(results, null, 2)}
    -
    -
    - - ); - } -} + _react.default.createElement(Body, null, + _react.default.createElement(Header, { success: success }, + _react.default.createElement(HeaderLeft, null, success ? 'Passed!' : 'Failed :('), + _react.default.createElement('div', null, + results.numPassedTests, ' of ', results.numTotalTests, ' passed')), -type ResultProps = { - result: TestResult, -}; -function ResultItem(props: ResultProps) { - const {result} = props; + + _react.default.createElement(Main, null, + _react.default.createElement(List, null, + results.testResults.map(result => + _react.default.createElement(ResultItem, { key: result.testFilePath, result: result }))), + + + _react.default.createElement('details', { style: { paddingLeft: 40 } }, + _react.default.createElement('summary', null, 'Raw Jest JSON Output (debug)'), + _react.default.createElement('pre', null, JSON.stringify(results, null, 2)))))); + + + + + }}exports.default = Jest; + + + + + +function ResultItem(props) { + const { result } = props; return ( -
  • - {result.testFilePath} - {result.failureMessage == null ? null : ( -
    {result.failureMessage}
    - )} -
    - - {result.testResults.map(test => ( - - ))} - -
    -
  • - ); + _react.default.createElement('li', null, + _react.default.createElement('span', null, result.testFilePath), + result.failureMessage == null ? null : + _react.default.createElement('pre', null, result.failureMessage), + + _react.default.createElement('details', { open: !result.failureMessage }, + _react.default.createElement(List, null, + result.testResults.map(test => + _react.default.createElement(SingleTestItem, { key: test.fullName, test: test })))))); + + + + + } -type SingleTestProps = { - test: AssertionResult, -}; -function SingleTestItem(props: SingleTestProps) { - const {test} = props; + + + +function SingleTestItem(props) { + const { test } = props; return ( -
  • - - {test.title} - {test.failureMessages.length > 0 ? ( - - {test.failureMessages.map(message => { - return ( -
  • -
    {message}
    -
  • - ); - })} - - ) : null} - - ); + _react.default.createElement('li', null, + _react.default.createElement((_Icon || _load_Icon()).Icon, { icon: statusToIcon[test.status] }), + _react.default.createElement('span', null, test.title), + test.failureMessages.length > 0 ? + _react.default.createElement(List, null, + test.failureMessages.map(message => { + return ( + _react.default.createElement('li', { key: message }, + _react.default.createElement('pre', null, message))); + + + })) : + + null)); + + } function Body(props) { return ( -
    - ); + height: '100vh' } }, + + props))); + + } function Header(props) { - const {success, ...restProps} = props; + const { success } = props,restProps = _objectWithoutProperties(props, ['success']); return ( -
    - ); + padding: 20 } }, + + restProps))); + + } -const HeaderLeft = function(props) { - return
    ; +const HeaderLeft = function (props) { + return _react.default.createElement('div', Object.assign({ style: { flex: 1 } }, props)); }; -const Main = function(props) { +const Main = function (props) { return ( -
    - ); + padding: '40px 0' } }, + + props))); + + }; -const List = function(props) { +const List = function (props) { return ( -
      - ); + paddingLeft: 40 } }, + + props))); + + }; const statusToIcon = { passed: 'check', failed: 'x', pending: 'dash', - skipped: 'dash', -}; + skipped: 'dash' }; \ No newline at end of file diff --git a/modules/nuclide-jest/types.js b/modules/nuclide-jest/types.js index 83813c33..a726efc4 100644 --- a/modules/nuclide-jest/types.js +++ b/modules/nuclide-jest/types.js @@ -1,141 +1 @@ -/** - * 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 - * @format - */ - -type ConsoleBuffer = Array; - -type LogMessage = string; -type LogEntry = {| - message: LogMessage, - origin: string, - type: LogType, -|}; - -type LogType = - | 'assert' - | 'count' - | 'debug' - | 'dir' - | 'dirxml' - | 'error' - | 'group' - | 'groupCollapsed' - | 'info' - | 'log' - | 'time' - | 'warn'; - -type SerializableError = {| - code?: mixed, - message: string, - stack: ?string, - type?: string, -|}; - -type RawFileCoverage = {| - path: string, - s: {[statementId: number]: number}, - b: {[branchId: number]: number}, - f: {[functionId: number]: number}, - l: {[lineId: number]: number}, - fnMap: {[functionId: number]: any}, - statementMap: {[statementId: number]: any}, - branchMap: {[branchId: number]: any}, - inputSourceMap?: Object, -|}; - -type RawCoverage = { - [filePath: string]: RawFileCoverage, -}; - -type Bytes = number; -type Milliseconds = number; - -export type TestResult = {| - console: ?ConsoleBuffer, - coverage?: RawCoverage, - displayName: ?string, - failureMessage: ?string, - leaks: boolean, - memoryUsage?: Bytes, - numFailingTests: number, - numPassingTests: number, - numPendingTests: number, - perfStats: {| - end: Milliseconds, - start: Milliseconds, - |}, - skipped: boolean, - snapshot: {| - added: number, - fileDeleted: boolean, - matched: number, - unchecked: number, - uncheckedKeys: Array, - unmatched: number, - updated: number, - |}, - sourceMaps: {[sourcePath: string]: string}, - testExecError?: SerializableError, - testFilePath: string, - testResults: Array, -|}; - -type Callsite = {| - column: number, - line: number, -|}; - -type Status = 'passed' | 'failed' | 'skipped' | 'pending'; - -export type AssertionResult = {| - ancestorTitles: Array, - duration?: ?Milliseconds, - failureMessages: Array, - fullName: string, - location: ?Callsite, - numPassingAsserts: number, - status: Status, - title: string, -|}; - -export type AggregatedResults = {| - numFailedTests: number, - numFailedTestSuites: number, - numPassedTests: number, - numPassedTestSuites: number, - numPendingTests: number, - numPendingTestSuites: number, - numRuntimeErrorTestSuites: number, - numTotalTests: number, - numTotalTestSuites: number, - snapshot: SnapshotSummary, - startTime: number, - success: boolean, - testResults: Array, - wasInterrupted: boolean, -|}; - -type SnapshotSummary = {| - added: number, - didUpdate: boolean, - failure: boolean, - filesAdded: number, - filesRemoved: number, - filesUnmatched: number, - filesUpdated: number, - matched: number, - total: number, - unchecked: number, - uncheckedKeys: Array, - unmatched: number, - updated: number, -|}; +'use strict'; \ No newline at end of file diff --git a/modules/nuclide-node-transpiler/spec/fixtures/modern-syntax.js b/modules/nuclide-node-transpiler/spec/fixtures/modern-syntax.js index 6beddeb7..b1fec7ff 100644 --- a/modules/nuclide-node-transpiler/spec/fixtures/modern-syntax.js +++ b/modules/nuclide-node-transpiler/spec/fixtures/modern-syntax.js @@ -1,15 +1,14 @@ -/** - * 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 - * @format - */ +'use strict';Object.defineProperty(exports, "__esModule", { value: true }); /** + * 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. + * + * + * @format + */ -export class Foo { - static bar = 'qux'; -} +class Foo {}exports.Foo = Foo;Foo. +bar = 'qux'; \ No newline at end of file diff --git a/package.json b/package.json index e62bc773..3741a6e2 100644 --- a/package.json +++ b/package.json @@ -105,6 +105,5 @@ "react-addons-test-utils": "15.3.1", "simple-text-buffer": "9.2.11", "yargs": "3.32.0" - }, - "private": true + } }